from __future__ import annotations
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
    from lib.core.translator import Translator
    from lib.core.LlvmCodeGenerator import LlvmCodeGenerator
import ast
import copy
import traceback
import llvmlite.ir as ir
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


# t 模块存储类标记装饰器名称集合
_T_STORAGE_DECORATORS = frozenset({'CExport', 'CExtern', 'CStatic', 'State', 'CInline', 'TLS'})


class FunctionHandle(BaseHandle):
    @staticmethod
    def _ExtractFuncMeta(decorator_list: list[ast.AST]) -> FuncMeta:
        meta: FuncMeta = FuncMeta.NONE
        if not decorator_list:
            return meta
        for d in decorator_list:
            if isinstance(d, ast.Name):
                if d.id == 'staticmethod':
                    meta |= FuncMeta.STATIC_METHOD
                elif d.id == 'property':
                    meta |= FuncMeta.PROPERTY_GETTER
                elif d.id == 'classmethod':
                    meta |= FuncMeta.CLASS_METHOD
            elif isinstance(d, ast.Attribute):
                if isinstance(d.value, ast.Name):
                    # 支持 @property.setter 和 @propname.setter 两种形式
                    # @propname.setter 中 propname 是之前用 @property 定义的同名属性
                    if d.value.id == 'property' or d.attr in ('setter', 'getter', 'deleter'):
                        if d.attr == 'setter':
                            meta |= FuncMeta.PROPERTY_SETTER
                        elif d.attr == 'getter':
                            meta |= FuncMeta.PROPERTY_GETTER
                        elif d.attr == 'deleter':
                            meta |= FuncMeta.PROPERTY_DELETER
        return meta

    def _extract_decorator_storage_flags(self, Node: ast.FunctionDef) -> dict[str, bool]:
        """从装饰器列表中提取 t 模块存储类标记

        支持 @t.CExport, @t.CExtern, @t.CStatic, @t.State, @t.CInline
        也支持 from t import CExport 等别名形式

        Returns:
            dict with keys: 'is_export', 'is_extern', 'is_static', 'is_state', 'is_inline'
        """
        flags: dict[str, bool] = {
            'is_export': False, 'is_extern': False,
            'is_static': False, 'is_state': False, 'is_inline': False,
        }
        if not Node.decorator_list:
            return flags
        symtab: object = self.Trans.SymbolTable
        for decorator in Node.decorator_list:
            attr_name: str | None = None
            # @t.CExport 形式
            if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name):
                if IsTModule(decorator.value.id, symtab):
                    attr_name = decorator.attr
            # @CExport 形式 (from t import CExport)
            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 and attr_name in _T_STORAGE_DECORATORS:
                if attr_name == 'CExport':
                    flags['is_export'] = True
                elif attr_name == 'CExtern':
                    flags['is_extern'] = True
                elif attr_name == 'CStatic':
                    flags['is_static'] = True
                elif attr_name == 'State':
                    flags['is_state'] = True
                elif attr_name == 'CInline':
                    flags['is_inline'] = True
        return flags

    @staticmethod
    def _is_t_storage_decorator(decorator: ast.AST, symtab: object) -> bool:
        """检查装饰器是否是 t 模块存储类标记（用于排除 behavior_decorators）"""
        attr_name: str | None = None
        if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name):
            if IsTModule(decorator.value.id, symtab):
                attr_name = decorator.attr
        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__
            elif decorator.id in _T_STORAGE_DECORATORS and hasattr(t, decorator.id):
                # TLS 是普通函数标记，不是 CType 子类
                attr_name = decorator.id
        return attr_name in _T_STORAGE_DECORATORS if attr_name else False

    # ------------------------------------------------------------------
    #  函数签名公共辅助：以下三个方法供 _GetFunctionSignatureLlvm 与
    #  _EmitFunctionLlvm 共享，避免 ~80 行重复代码。
    # ------------------------------------------------------------------

    def _compute_func_name_meta(self, Node: ast.FunctionDef, ClassName: str | None) -> tuple[str, str, FuncMeta]:
        """计算函数全名（含 setter/deleter 后缀）和 func_meta

        Returns:
            (FuncName, RawFuncName, func_meta)
        """
        RawFuncName: str = Node.name
        FuncName: str = f"{ClassName}.{RawFuncName}" if ClassName else RawFuncName
        func_meta: FuncMeta = self._ExtractFuncMeta(Node.decorator_list)
        # property setter/deleter 使用不同的函数名后缀，避免与 getter 冲突
        if FuncMeta.PROPERTY_SETTER in func_meta:
            FuncName = FuncName + '$set'
        elif FuncMeta.PROPERTY_DELETER in func_meta:
            FuncName = FuncName + '$del'
        return FuncName, RawFuncName, func_meta

    def _resolve_method_class(self, Node: ast.FunctionDef, ClassName: str | None, func_meta: FuncMeta, FuncName: str, Gen: LlvmCodeGenerator) -> tuple[bool, bool, str | None]:
        """判定函数是否是实例方法 / 类方法，并解析所属类名

        Returns:
            (IsMethod, IsClassMethod, ResolvedClassName)
        """
        RawFuncName: str = Node.name
        IsMethod: bool = False
        IsClassMethod: bool = False
        ResolvedClassName: str | None = ClassName
        if not ResolvedClassName:
            for potential_class in Gen.class_methods:
                if FuncName.startswith(f"{potential_class}."):
                    IsMethod = True
                    ResolvedClassName = potential_class
                    break
        else:
            IsMethod = FuncMeta.STATIC_METHOD not in func_meta and FuncMeta.CLASS_METHOD not in func_meta
            IsClassMethod = FuncMeta.CLASS_METHOD in func_meta
            if RawFuncName == '__init__':
                IsMethod = False
        return IsMethod, IsClassMethod, ResolvedClassName

    def _apply_struct_self_cls_types(self, ParamTypes: list[ir.Type], ParamNames: list[str], IsMethod: bool, IsClassMethod: bool, ResolvedClassName: str | None, Gen: LlvmCodeGenerator) -> bool:
        """根据 IsMethod / IsClassMethod 调整 self/cls 参数的 LLVM 类型

        - 若是实例方法且无 self 参数，自动插入一个 struct 指针类型；
          此时调用方需要同步插入对应的 ParamTypeStrs（本方法不维护）。
        - 若是 @classmethod，将 cls 参数覆盖为 struct 指针类型。

        Returns:
            True 表示为实例方法自动插入了 self 参数；False 表示未插入。
        """
        if not ResolvedClassName or ResolvedClassName not in Gen.structs:
            return False
        # 治本修复：同名类 sha1 冲突检测。
        # 当多个模块定义同名类（如 stmts.py:Module 和 __module.py:Module）时，
        # Gen.structs[short_name] 可能指向错误模块的 struct（set_body 已锁定错误布局）。
        # 通过 class_sha1_map 获取当前类的源模块 sha1，查找以 sha1 为前缀的完整 struct。
        TargetStruct: ir.IdentifiedStructType = Gen.structs[ResolvedClassName]
        ClassSha1Map: dict[str, str] = getattr(Gen, 'class_sha1_map', {})
        ExpectedSha1: str | None = ClassSha1Map.get(ResolvedClassName)
        if ExpectedSha1 and isinstance(TargetStruct, ir.IdentifiedStructType):
            ExistingSha1: str = Gen._extract_struct_sha1(TargetStruct)
            if ExistingSha1 and ExistingSha1 != ExpectedSha1:
                # sha1 冲突：查找或创建正确的 struct
                FullKey: str = f"{ExpectedSha1}.{ResolvedClassName}"
                if FullKey in Gen.structs:
                    TargetStruct = Gen.structs[FullKey]
                else:
                    # 创建新 struct 并从 stub 加载 body
                    TargetStruct = Gen._get_or_create_struct(ResolvedClassName, source_sha1=ExpectedSha1)
                    if hasattr(self.Trans, 'ImportHandler'):
                        self.Trans.ImportHandler._TryLoadStructFromStub(ResolvedClassName, Gen, source_sha1=ExpectedSha1)
                        if FullKey in Gen.structs:
                            TargetStruct = Gen.structs[FullKey]
                # 安全回退：如果新 struct 仍为 opaque（body 未加载），回退到原始短名 struct，
                # 避免方法编译生成无效 GEP（访问 opaque struct 元素）导致运行时崩溃。
                if isinstance(TargetStruct, ir.IdentifiedStructType):
                    try:
                        _is_opaque: bool = TargetStruct.is_opaque
                    except (AssertionError, AttributeError):
                        _is_opaque = False
                    if _is_opaque:
                        TargetStruct = Gen.structs[ResolvedClassName]
        if IsMethod:
            StructPtrType: ir.PointerType = ir.PointerType(TargetStruct)
            SelfIdx: int = next((i for i, n in enumerate(ParamNames) if n == "self"), -1)
            if SelfIdx >= 0:
                ParamTypes[SelfIdx] = StructPtrType
                return False
            ParamTypes.insert(0, StructPtrType)
            ParamNames.insert(0, "self")
            return True
        # 非方法但属于类（如 staticmethod / 顶层函数位于类下）
        SelfIdx = next((i for i, n in enumerate(ParamNames) if n == "self"), -1)
        if SelfIdx >= 0:
            StructPtrType = ir.PointerType(TargetStruct)
            ParamTypes[SelfIdx] = StructPtrType
        if IsClassMethod:
            ClsIdx: int = next((i for i, n in enumerate(ParamNames) if n == "cls"), -1)
            if ClsIdx >= 0:
                StructPtrType = ir.PointerType(TargetStruct)
                ParamTypes[ClsIdx] = StructPtrType
        return False

    def _body_contains_raise(self, body: list[ast.AST]) -> bool:
        for node in ast.walk(ast.Module(body=body, type_ignores=[])):
            if isinstance(node, ast.Raise):
                if node.exc:
                    if isinstance(node.exc, ast.Name) and node.exc.id == 'StopIteration':
                        continue
                    if isinstance(node.exc, ast.Call) and isinstance(node.exc.func, ast.Name) and node.exc.func.id == 'StopIteration':
                        continue
                return True
            if isinstance(node, ast.Call):
                called_name: str | None = None
                if isinstance(node.func, ast.Name):
                    called_name = node.func.id
                elif isinstance(node.func, ast.Attribute):
                    called_name = node.func.attr
                if called_name:
                    Gen: LlvmCodeGenerator = self.Trans.LlvmGen
                    for prefix in ['', f'{called_name}.', f'__']:
                        for suffix in ['', f'.{called_name}']:
                            fname: str = f'{prefix}{called_name}{suffix}'
                            if fname in Gen.functions:
                                func: Any = Gen.functions[fname]
                                if len(func.args) > 0:
                                    for arg in func.args:
                                        if hasattr(arg, 'name') and arg.name in ('__eh_msg_out__', '__eh_code_out__'):
                                            return True
                                break
        return False

    _LLVM_ATTR_NAMES = frozenset({
        'nobuiltin', 'nounwind', 'noredzone', 'willreturn', 'mustprogress',
        'optnone', 'noinline', 'alwaysinline', 'readnone', 'readonly',
        'writeonly', 'inaccessiblememonly', 'inaccessiblemem_or_argmemonly',
    })

    def _ExtractLLVMAttrs(self, node: ast.AST) -> list[str]:
        attrs: list[str] = []
        if isinstance(node, ast.BinOp):
            attrs.extend(self._ExtractLLVMAttrs(node.left))
            attrs.extend(self._ExtractLLVMAttrs(node.right))
        elif isinstance(node, ast.Attribute):
            attr_name: str | None = self._GetAttrLLVMName(node)
            if attr_name:
                attrs.append(attr_name)
        return attrs

    def _GetAttrLLVMName(self, node: ast.AST) -> str | None:
        if not isinstance(node, ast.Attribute):
            return None
        if node.attr not in self._LLVM_ATTR_NAMES:
            return None
        value: ast.AST = node.value
        if not isinstance(value, ast.Attribute) or value.attr != 'llvm':
            return None
        inner: ast.AST = value.value
        if not isinstance(inner, ast.Attribute) or inner.attr != 'attr':
            return None
        if not isinstance(inner.value, ast.Name) or inner.value.id != 't':
            return None
        return node.attr

    def _infer_return_type_from_body(self, Node: ast.AST, Gen: LlvmCodeGenerator | None = None, ClassName: str | None = None) -> tuple[str, bool] | None:
        local_var_types: dict[str, tuple[str, bool]] = {}
        for child in ast.walk(Node):
            if isinstance(child, ast.Assign) and len(child.targets) == 1:
                target: ast.AST = child.targets[0]
                if isinstance(target, ast.Name) and isinstance(child.value, ast.Subscript):
                    sub: ast.Subscript = child.value
                    if (isinstance(sub.value, ast.Attribute)
                        and isinstance(sub.value.value, ast.Name)
                        and sub.value.value.id == 'self'
                        and ClassName and ClassName in Gen.class_members):
                        member_name: str = sub.value.attr
                        for m_name, m_type in Gen.class_members[ClassName]:
                            if m_name == member_name:
                                if isinstance(m_type, ir.ArrayType):
                                    elem_type: ir.Type = m_type.element
                                    if isinstance(elem_type, ir.FloatType):
                                        local_var_types[target.id] = ('float', False)
                                    elif isinstance(elem_type, ir.DoubleType):
                                        local_var_types[target.id] = ('double', False)
                                    elif isinstance(elem_type, ir.IntType):
                                        if elem_type.width == 8:
                                            local_var_types[target.id] = ('char', False)
                                        else:
                                            local_var_types[target.id] = ('int', False)
                                    elif isinstance(elem_type, ir.PointerType):
                                        if isinstance(elem_type.pointee, ir.IntType) and elem_type.pointee.width == 8:
                                            local_var_types[target.id] = ('char', True)
                                        else:
                                            local_var_types[target.id] = ('void', True)
                                    elif isinstance(elem_type, ir.IdentifiedStructType):
                                        struct_name: str = elem_type.name
                                        if struct_name:
                                            for sn, st in Gen.structs.items():
                                                if st.name == struct_name or sn == struct_name:
                                                    local_var_types[target.id] = (sn, False)
                                                    break
                                        else:
                                            local_var_types[target.id] = (elem_type.name, False)
                                elif isinstance(m_type, ir.PointerType):
                                    pointee: ir.Type = m_type.pointee
                                    if isinstance(pointee, ir.FloatType):
                                        local_var_types[target.id] = ('float', False)
                                    elif isinstance(pointee, ir.DoubleType):
                                        local_var_types[target.id] = ('double', False)
                                    elif isinstance(pointee, ir.IntType):
                                        if pointee.width == 8:
                                            local_var_types[target.id] = ('char', False)
                                        else:
                                            local_var_types[target.id] = ('int', False)
                                    elif isinstance(pointee, ir.PointerType):
                                        local_var_types[target.id] = ('void', True)
                                    elif isinstance(pointee, ir.IdentifiedStructType):
                                        for sn, st in Gen.structs.items():
                                            if st == pointee or st.name == pointee.name:
                                                local_var_types[target.id] = (sn, True)
                                                break
                                break
        for child in ast.walk(Node):
            if isinstance(child, ast.Return) and child.value:
                val: ast.AST = child.value
                if isinstance(val, ast.Name) and val.id == 'self' and ClassName:
                    return (ClassName, True)
                if isinstance(val, ast.Call):
                    if isinstance(val.func, ast.Name):
                        callee: str = val.func.id
                        if callee == 'malloc':
                            return ('char', True)
                        if callee == 'chr':
                            return ('char', False)
                        if Gen and callee in Gen.functions:
                            func: Any = Gen.functions[callee]
                            if hasattr(func, 'ftype'):
                                ret_type: ir.Type = func.ftype.return_type
                                if isinstance(ret_type, ir.PointerType):
                                    if isinstance(ret_type.pointee, ir.IntType) and ret_type.pointee.width == 8:
                                        return ('char', True)
                                    return ('void', True)
                                elif isinstance(ret_type, ir.IntType):
                                    if ret_type.width == 8:
                                        return ('char', False)
                                    return ('int', False)
                                elif isinstance(ret_type, ir.VoidType):
                                    return ('void', False)
                    elif isinstance(val.func, ast.Attribute):
                        pass
                    callee_name: str | None = None
                    if isinstance(val.func, ast.Name):
                        callee_name = val.func.id
                    elif isinstance(val.func, ast.Attribute):
                        callee_name = getattr(val.func, 'attr', None)
                    if callee_name:
                        sym: Any = self.Trans.SymbolTable.lookup(callee_name)
                        if sym and isinstance(sym, dict):
                            ret_type_str: str = sym.get('return_type', '')
                            if ret_type_str and ret_type_str != 'int':
                                IsPtr: bool = sym.get('IsPtr', False)
                                return (ret_type_str, IsPtr)
                elif isinstance(val, ast.Constant):
                    if val.value is None:
                        return ('char', True)
                    elif isinstance(val.value, str) and len(val.value) <= 1:
                        return ('char', True)
                elif isinstance(val, ast.Name):
                    var_name: str = val.id
                    if var_name in local_var_types:
                        return local_var_types[var_name]
                    var_info: Any = self.Trans.SymbolTable.lookup(var_name)
                    if var_info and isinstance(var_info, dict):
                        var_type: str = var_info.get('type', '')
                        if var_type and var_type != 'int':
                            IsPtr: bool = var_info.get('IsPtr', False)
                            return (var_type, IsPtr)
                elif isinstance(val, ast.Subscript):
                    if (isinstance(val.value, ast.Attribute)
                        and isinstance(val.value.value, ast.Name)
                        and val.value.value.id == 'self'
                        and ClassName):
                        member_name: str = val.value.attr
                        if ClassName in Gen.class_members:
                            for m_name, m_type in Gen.class_members[ClassName]:
                                if m_name == member_name:
                                    if isinstance(m_type, ir.ArrayType):
                                        elem_type: ir.Type = m_type.element
                                        if isinstance(elem_type, ir.FloatType):
                                            return ('float', False)
                                        elif isinstance(elem_type, ir.DoubleType):
                                            return ('double', False)
                                        elif isinstance(elem_type, ir.IntType):
                                            if elem_type.width == 8:
                                                return ('char', False)
                                            return ('int', False)
                                        elif isinstance(elem_type, ir.PointerType):
                                            if isinstance(elem_type.pointee, ir.IntType) and elem_type.pointee.width == 8:
                                                return ('char', True)
                                            return ('void', True)
                                        elif isinstance(elem_type, ir.IdentifiedStructType):
                                            struct_name: str = elem_type.name
                                            if struct_name:
                                                for sn, st in Gen.structs.items():
                                                    if st.name == struct_name or sn == struct_name:
                                                        return (sn, False)
                                            return (elem_type.name, False)
                                    elif isinstance(m_type, ir.PointerType):
                                        pointee: ir.Type = m_type.pointee
                                        if isinstance(pointee, ir.FloatType):
                                            return ('float', False)
                                        elif isinstance(pointee, ir.DoubleType):
                                            return ('double', False)
                                        elif isinstance(pointee, ir.IntType):
                                            if pointee.width == 8:
                                                return ('char', False)
                                            return ('int', False)
                                        elif isinstance(pointee, ir.PointerType):
                                            return ('void', True)
                                        elif isinstance(pointee, ir.IdentifiedStructType):
                                            for sn, st in Gen.structs.items():
                                                if st == pointee or st.name == pointee.name:
                                                    return (sn, True)
                                            return (pointee.name, True)
                                    break
                    if isinstance(val.value, ast.Name):
                        var_name: str = val.value.id
                        var_info: Any = self.Trans.SymbolTable.lookup(var_name)
                        if var_info and isinstance(var_info, dict):
                            var_type: str = var_info.get('type', '')
                            if var_type.startswith('list[') or var_type.startswith('List[') or var_type.startswith('t.CArray['):
                                inner: str = var_type[var_type.index('[') + 1:var_type.rindex(']')]
                                parts: list[str] = inner.split(',')
                                elem_type_str: str = parts[0].strip()
                                if elem_type_str and elem_type_str != 'int':
                                    IsPtr: bool = var_info.get('IsPtr', False)
                                    return (elem_type_str, IsPtr)
        return None

    def _GetFunctionSignatureLlvm(self, Node: ast.FunctionDef, Gen: LlvmCodeGenerator, ClassName: str | None = None, extra_params: list[tuple[str, Any]] | None = None) -> tuple[str, ir.FunctionType, Any, list[Any], list[ast.AST], bool, str | None, bool]:
        FuncName, RawFuncName, func_meta = self._compute_func_name_meta(Node, ClassName)
        CReturnTypes: list[ast.AST] = []
        if Node.decorator_list:
            for decorator in Node.decorator_list:
                if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
                    if decorator.func.attr == 'CReturn':
                        for arg in decorator.args:
                            CReturnTypes.append(arg)
        if Node.returns:
            llvm_attrs: list[str] = self._ExtractLLVMAttrs(Node.returns)
            if llvm_attrs:
                if not hasattr(self, '_pending_llvm_attrs'):
                    self._pending_llvm_attrs = {}
                self._pending_llvm_attrs[FuncName] = llvm_attrs
            if isinstance(Node.returns, ast.Subscript) and isinstance(Node.returns.value, ast.Name) and Node.returns.value.id == 'tuple':
                slice_node: ast.AST = Node.returns.slice
                if isinstance(slice_node, ast.Tuple):
                    for elt in slice_node.elts:
                        CReturnTypes.append(elt)
                else:
                    CReturnTypes.append(slice_node)
        IsPtr: bool = False
        ReturnTypeInfo: Any = None
        if Node.returns:
            if CReturnTypes:
                ReturnTypeInfo = CTypeInfo()
                ReturnTypeInfo.BaseType = t.CVoid()
            else:
                try:
                    if isinstance(Node.returns, ast.BinOp) and isinstance(Node.returns.op, ast.BitOr):
                        ReturnTypeInfo = getattr(self.Trans, 'TypeMergeHandler', None) and self.Trans.TypeMergeHandler.MergeTypes(Node.returns)
                        if not isinstance(ReturnTypeInfo, CTypeInfo):
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CVoid()
                        if (ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState) or ReturnTypeInfo.PtrCount >= 2:
                            def _FindNonVoidCTypeInfo(node: ast.AST) -> Any:
                                if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
                                    results: list[Any] = []
                                    for child in [node.left, node.right]:
                                        r: Any = _FindNonVoidCTypeInfo(child)
                                        if r and not r.IsVoid:
                                            results.append(r)
                                    for r in results:
                                        if not r.IsPtr and not r.IsStruct:
                                            return r
                                    return results[0] if results else None
                                try:
                                    SideInfo: Any = CTypeInfo.FromNode(node, self.Trans.SymbolTable)
                                    if SideInfo:
                                        return SideInfo
                                except Exception as _e:
                                    if _config_mode == "strict":
                                        self.Trans.LogWarning(f"异常被忽略: {_e}")
                                return None
                            found: Any = _FindNonVoidCTypeInfo(Node.returns)
                            if found and not found.IsVoid:
                                ReturnTypeInfo = found
                        if ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CInt()
                    else:
                        is_str_type: bool = False
                        if isinstance(Node.returns, ast.Name) and Node.returns.id in ('str', 'bytes'):
                            is_str_type = True
                        ReturnTypeInfo = CTypeInfo.FromNode(Node.returns, self.Trans.SymbolTable)
                        if ReturnTypeInfo and ReturnTypeInfo.IsDefine:
                            inferred: Any = self._infer_return_type_from_body(Node, Gen, ClassName)
                            if inferred:
                                ReturnTypeInfo = CTypeInfo.FromTypeName(inferred[0])
                                ReturnTypeInfo.PtrCount = 1 if inferred[1] else 0
                            else:
                                ReturnTypeInfo = CTypeInfo()
                                ReturnTypeInfo.BaseType = t.CInt()
                            if not hasattr(self, '_cdefine_funcs'):
                                self._cdefine_funcs = set()
                            self._cdefine_funcs.add(FuncName)
                        elif ReturnTypeInfo and ReturnTypeInfo.IsState:
                            if ReturnTypeInfo.PtrCount > 0 or (ReturnTypeInfo.BaseType and not isinstance(ReturnTypeInfo.BaseType, t.CVoid)):
                                pass
                            else:
                                ReturnTypeInfo = CTypeInfo()
                                ReturnTypeInfo.BaseType = t.CVoid()
                        if ReturnTypeInfo is None:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CVoid()
                        if is_str_type or ReturnTypeInfo.IsStr:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CChar()
                            ReturnTypeInfo.PtrCount = 1
                        # 检查泛型类返回类型 (如 list[str])
                        # 注意：_from_node_subscript 对未识别的泛型下标（如 list[str]）返回空 CTypeInfo（BaseType=None），
                        # 此时 IsVoid 为 False（因为 IsVoid 仅检查 t.CVoid 实例），需额外检测 BaseType is None
                        if (isinstance(Node.returns, ast.Subscript)
                            and isinstance(Node.returns.value, ast.Name)
                            and hasattr(self.Trans.ClassHandler, '_generic_class_templates')
                            and Node.returns.value.id in self.Trans.ClassHandler._generic_class_templates
                            and (ReturnTypeInfo.IsVoid or ReturnTypeInfo.BaseType is None) and ReturnTypeInfo.PtrCount == 0):
                            ret_class: str = Node.returns.value.id
                            ret_slice: ast.AST = Node.returns.slice
                            ret_type_args: list[str] = []
                            ret_type_names: list[str] = []
                            if isinstance(ret_slice, ast.Tuple):
                                for elt in ret_slice.elts:
                                    if isinstance(elt, ast.Name):
                                        tn2: str = elt.id
                                        ts2: str = tn2
                                        if tn2 == 'int':
                                            ts2, tn2 = 'int', 'CInt'
                                        ret_type_args.append(ts2)
                                        ret_type_names.append(tn2)
                            elif isinstance(ret_slice, ast.Name):
                                tn2: str = ret_slice.id
                                ts2: str = tn2
                                if tn2 == 'int':
                                    ts2, tn2 = 'int', 'CInt'
                                ret_type_args.append(ts2)
                                ret_type_names.append(tn2)
                            # 返回类型解析只需 struct 定义，不需方法体；使用 declare_only=True
                            # 避免过早触发完整特化（此时 MemManager.alloc 可能尚未注册，
                            # 导致 __new__ 的 pool.alloc(48) 解析失败，IR 块未终止）。
                            # 完整特化由后续类实例化（L3688/L3753）触发 declare_only=False。
                            spec_name2: str | None = self.Trans.ClassHandler._specialize_generic_class(
                                ret_class, ret_type_args, Gen, type_names=ret_type_names, declare_only=True)
                            if spec_name2 and spec_name2 in Gen.structs:
                                ReturnTypeInfo = CTypeInfo()
                                ReturnTypeInfo.BaseType = t.CStruct(name=spec_name2)
                                ReturnTypeInfo.PtrCount = 1
                        if (ReturnTypeInfo.IsVoid or ReturnTypeInfo.BaseType is None) and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CInt()
                except Exception:  # 回退：设置默认返回类型为 CInt
                    ReturnTypeInfo = CTypeInfo()
                    ReturnTypeInfo.BaseType = t.CInt()
        else:
            ReturnTypeInfo = CTypeInfo()
            ReturnTypeInfo.BaseType = t.CInt()
            inferred: Any = self._infer_return_type_from_body(Node, Gen, ClassName)
            if inferred:
                ReturnTypeInfo = CTypeInfo.FromTypeName(inferred[0])
                ReturnTypeInfo.PtrCount = 1 if inferred[1] else 0
        IsPtr = ReturnTypeInfo.IsPtr if ReturnTypeInfo else False
        ReturnType: ir.Type = Gen._ctype_to_llvm(ReturnTypeInfo)
        if isinstance(ReturnType, ir.PointerType) and isinstance(ReturnType.pointee, ir.PointerType):
            if isinstance(ReturnType.pointee.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                ReturnType = ir.PointerType(ReturnType.pointee.pointee)
        if isinstance(ReturnType, ir.IntType) and ReturnType.width == 8:
            if RawFuncName == '__str__':
                ReturnType = ir.PointerType(ir.IntType(8))
        if isinstance(ReturnType, ir.VoidType) and FuncName == 'main':
            ReturnType = ir.IntType(32)
        IsMethod, IsClassMethod, ResolvedClassName = self._resolve_method_class(Node, ClassName, func_meta, FuncName, Gen)
        # __new__ methods should return a pointer to the struct (for heap allocation replacement)
        # 修复：前向声明也必须使用正确的返回类型，否则 _replace_function_decl 可能失败，
        # 导致 vtable 引用错误的函数类型（i32 而非 ClassName*）
        if RawFuncName == '__new__' and ResolvedClassName:
            StructType = Gen.structs.get(ResolvedClassName)
            if StructType:
                if isinstance(StructType, ir.PointerType):
                    ReturnType = StructType
                else:
                    ReturnType = ir.PointerType(StructType)
        ParamTypes: list[ir.Type] = []
        ParamNames: list[str] = []
        ParamTypeStrs: list[Any] = []
        auto_addr_modes: list[str | None] = []
        CReturnLlvmTypes: list[ir.Type] = []
        if CReturnTypes:
            for i, ReturnTypeNode in enumerate(CReturnTypes):
                ReturnTypeInfo = CTypeInfo.FromNode(ReturnTypeNode, self.Trans.SymbolTable)
                if ReturnTypeInfo and ReturnTypeInfo.IsStr:
                    ReturnTypeInfo = CTypeInfo()
                    ReturnTypeInfo.BaseType = t.CChar()
                    ReturnTypeInfo.PtrCount = 1
                if ReturnTypeInfo is None:
                    ReturnTypeInfo = CTypeInfo()
                    ReturnTypeInfo.BaseType = t.CInt()
                RetType: ir.Type = Gen._ctype_to_llvm(ReturnTypeInfo)
                CReturnLlvmTypes.append(RetType)
            ReturnType = ir.LiteralStructType(CReturnLlvmTypes)
        for Arg in Node.args.args:
            ParamIsUnsigned: bool = False
            if Arg.annotation:
                try:
                    ParamTypeInfo: Any
                    ParamTypeInfo = self.ResolveAnnotationType(Arg.annotation)
                    if ParamTypeInfo is None:
                        ParamTypeInfo = CTypeInfo()
                        ParamTypeInfo.BaseType = t.CInt()
                    IsPtr = ParamTypeInfo.IsPtr
                    if ParamTypeInfo and getattr(ParamTypeInfo, 'IsCpythonObject', False) and not IsPtr:
                        IsPtr = True
                        ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1)
                    if ParamTypeInfo.IsStr or (isinstance(Arg.annotation, ast.Name) and Arg.annotation.id in ('str', 'bytes')):
                        ParamTypeInfo = CTypeInfo()
                        ParamTypeInfo.BaseType = t.CChar()
                        ParamTypeInfo.PtrCount = 1
                        IsPtr = True
                    # C 语言中数组参数退化为指针：list[type, N] → type*
                    if ParamTypeInfo.ArrayDims:
                        ParamTypeInfo.ArrayDims = []
                        ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1)
                    ParamType: ir.Type = Gen._ctype_to_llvm(ParamTypeInfo)
                    ParamTypeStr: Any = ParamTypeInfo
                except Exception as e:
                    ParamType = ir.IntType(32)
                    ParamTypeStr = CTypeInfo()
                    ParamTypeStr.BaseType = t.CInt()
            else:
                if ClassName and Arg.arg != 'self':
                    op_method_names: list[str] = ['__add__', '__sub__', '__mul__', '__truediv__', '__floordiv__', '__mod__', '__pow__',
                                       '__radd__', '__rsub__', '__rmul__', '__rtruediv__', '__rfloordiv__', '__rmod__', '__rpow__',
                                       '__iadd__', '__isub__', '__imul__', '__itruediv__', '__ifloordiv__', '__imod__', '__ipow__',
                                       '__eq__', '__ne__', '__lt__', '__le__', '__gt__', '__ge__',
                                       '__neg__', '__pos__', '__abs__', '__call__']
                    if RawFuncName in op_method_names and ClassName in Gen.structs:
                        ParamType = ir.PointerType(Gen.structs[ClassName])
                    else:
                        ParamType = ir.IntType(32)
                else:
                    ParamType = ir.IntType(32)
                ParamTypeStr = CTypeInfo()
                ParamTypeStr.BaseType = t.CInt()
            ParamTypes.append(ParamType)
            ParamNames.append(Arg.arg)
            ParamTypeStrs.append(ParamTypeStr)
            # 检测 t.CNeedPtr / t.CAutoPtr 参数注解
            auto_mode: str | None = None
            if ParamTypeStr is not None and hasattr(ParamTypeStr, 'BaseType') and ParamTypeStr.BaseType is not None:
                if isinstance(ParamTypeStr.BaseType, t.CAutoPtr):
                    auto_mode = 'always'
                elif isinstance(ParamTypeStr.BaseType, t.CNeedPtr):
                    auto_mode = 'need'
            auto_addr_modes.append(auto_mode)
        if self._apply_struct_self_cls_types(ParamTypes, ParamNames, IsMethod, IsClassMethod, ResolvedClassName, Gen):
            ParamTypeStrs.insert(0, f"struct {ResolvedClassName}")
        IsVariadic: bool = Node.args.vararg is not None
        if extra_params:
            for var_name, ptr_type in extra_params:
                ParamTypes.append(ptr_type)
                ParamNames.append(f'__nonlocal_{var_name}__')
        if IsMethod and RawFuncName == '__next__':
            ParamTypes.append(ir.PointerType(ir.IntType(1)))
            ParamNames.append('__stop_iter_flag__')
        HasRaise: bool = self._body_contains_raise(Node.body)
        if HasRaise and RawFuncName != 'main':
            ParamTypes.append(ir.PointerType(ir.PointerType(ir.IntType(8))))
            ParamNames.append('__eh_msg_out__')
            ParamTypes.append(ir.PointerType(ir.IntType(32)))
            ParamNames.append('__eh_code_out__')
        FuncType: ir.FunctionType = ir.FunctionType(ReturnType, ParamTypes, var_arg=IsVariadic)
        # 存储 auto_addr_modes（为额外参数补 None）
        total_params: int = len(ParamTypes)
        while len(auto_addr_modes) < total_params:
            auto_addr_modes.append(None)
        Gen._auto_addr_params[FuncName] = auto_addr_modes
        return FuncName, FuncType, ReturnTypeInfo, ParamTypeStrs, CReturnTypes, IsMethod, ResolvedClassName, IsVariadic

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

    def _mangle_generic_name(self, func_name: str, type_args: list[str], has_cexport: bool = False) -> 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)
        if has_cexport:
            return func_name + '_T_' + '_'.join(mangled_args)
        return func_name + '[' + ']['.join(mangled_args) + ']'

    def _apply_type_map_to_node(self, Node: ast.FunctionDef, type_map: dict[str, str], cptr_params: set[str] | None = None) -> None:
        for arg in Node.args.args:
            if arg.annotation:
                arg.annotation = self._replace_type_in_annotation(arg.annotation, type_map, cptr_params)
        if Node.returns:
            Node.returns = self._replace_type_in_annotation(Node.returns, type_map, cptr_params)
        self._apply_type_map_to_body(Node.body, type_map, cptr_params)

    def _replace_type_in_annotation(self, node: ast.AST, type_map: dict[str, str], cptr_params: set[str] | None = None) -> ast.AST:
        if isinstance(node, ast.Name):
            if node.id in type_map:
                replacement: str = type_map[node.id]
                return self._make_replacement_node(replacement)
        elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
            if isinstance(node.left, ast.Name) and node.left.id in type_map:
                replacement: str = type_map[node.left.id]
                node.left = self._make_replacement_node(replacement)
                return node
            node.left = self._replace_type_in_annotation(node.left, type_map, cptr_params)
            node.right = self._replace_type_in_annotation(node.right, type_map, cptr_params)
        elif isinstance(node, ast.Attribute):
            if hasattr(node, 'attr') and node.attr in type_map:
                replacement: str = type_map[node.attr]
                return self._make_replacement_node(replacement)
        elif isinstance(node, ast.Subscript):
            # 嵌套泛型（如 list[T]）：递归替换 value 和 slice 中的类型参数
            node.value = self._replace_type_in_annotation(node.value, type_map, cptr_params)
            node.slice = self._replace_type_in_annotation(node.slice, type_map, cptr_params)
        return node

    def _make_replacement_node(self, replacement: str) -> ast.AST:
        """将 type_map 中的替换字符串转换为 AST 节点。
        mangled 名称如 'sha1.ASTptr' 需要还原为 AST | t.CPtr 结构，
        否则类型解析会丢失 PtrCount 信息。
        含点号的名称（如 'sha1.AST'）需解析为 ast.Attribute 链。
        """
        if replacement.endswith('ptr'):
            # 提取基础名称: 'sha1.ASTptr' -> 'sha1.AST'
            base: str = replacement[:-3]
            return ast.BinOp(
                left=self._make_name_node(base),
                op=ast.BitOr(),
                right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load())
            )
        return self._make_name_node(replacement)

    @staticmethod
    def _make_name_node(name: str) -> ast.AST:
        """将可能含点号的名称转换为 ast.Name 或 ast.Attribute 链。
        'AST' -> ast.Name(id='AST')
        'sha1.AST' -> ast.Attribute(value=ast.Name(id='sha1'), attr='AST')
        """
        if '.' not in name:
            return ast.Name(id=name, ctx=ast.Load())
        parts: list[str] = name.split('.')
        node: ast.AST = ast.Name(id=parts[0], ctx=ast.Load())
        for part in parts[1:]:
            node = ast.Attribute(value=node, attr=part, ctx=ast.Load())
        return node

    def _apply_type_map_to_body(self, body: list[ast.AST], type_map: dict[str, str], cptr_params: set[str] | None = None) -> None:
        for stmt in body:
            self._apply_type_map_to_stmt(stmt, type_map, cptr_params)

    def _apply_type_map_to_stmt(self, node: ast.AST, type_map: dict[str, str], cptr_params: set[str] | None = None) -> None:
        if isinstance(node, ast.Return) and node.value:
            self._apply_type_map_to_expr(node.value, type_map, cptr_params)
        elif isinstance(node, ast.Assign):
            for t in node.targets:
                self._apply_type_map_to_expr(t, type_map, cptr_params)
            self._apply_type_map_to_expr(node.value, type_map, cptr_params)
        elif isinstance(node, ast.AnnAssign):
            if node.annotation:
                node.annotation = self._replace_type_in_annotation(node.annotation, type_map, cptr_params)
            if node.value:
                self._apply_type_map_to_expr(node.value, type_map, cptr_params)
        elif isinstance(node, ast.AugAssign):
            self._apply_type_map_to_expr(node.target, type_map, cptr_params)
            self._apply_type_map_to_expr(node.value, type_map, cptr_params)
        elif isinstance(node, ast.Expr):
            self._apply_type_map_to_expr(node.value, type_map, cptr_params)
        elif isinstance(node, ast.If):
            self._apply_type_map_to_expr(node.test, type_map, cptr_params)
            for s in node.body:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
            for s in node.orelse:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
        elif isinstance(node, ast.For):
            self._apply_type_map_to_expr(node.iter, type_map, cptr_params)
            for s in node.body:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
            for s in node.orelse:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
        elif isinstance(node, ast.While):
            self._apply_type_map_to_expr(node.test, type_map, cptr_params)
            for s in node.body:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
            for s in node.orelse:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
        elif isinstance(node, ast.Try):
            for s in node.body:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
            for handler in node.handlers:
                for s in handler.body:
                    self._apply_type_map_to_stmt(s, type_map, cptr_params)
            for s in node.orelse:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
            for s in node.finalbody:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
        elif isinstance(node, ast.With):
            for item in node.items:
                self._apply_type_map_to_expr(item.context_expr, type_map, cptr_params)
                if item.optional_vars:
                    self._apply_type_map_to_expr(item.optional_vars, type_map, cptr_params)
            for s in node.body:
                self._apply_type_map_to_stmt(s, type_map, cptr_params)
        elif isinstance(node, ast.Raise):
            if node.exc:
                self._apply_type_map_to_expr(node.exc, type_map, cptr_params)
            if node.cause:
                self._apply_type_map_to_expr(node.cause, type_map, cptr_params)
        elif isinstance(node, ast.Assert):
            self._apply_type_map_to_expr(node.test, type_map, cptr_params)
            if node.msg:
                self._apply_type_map_to_expr(node.msg, type_map, cptr_params)

    def _apply_type_map_to_expr(self, node: ast.AST | None, type_map: dict[str, str], cptr_params: set[str] | None = None) -> None:
        if node is None:
            return
        if isinstance(node, ast.Call):
            if isinstance(node.func, ast.Name) and node.func.id in type_map:
                replacement: str = type_map[node.func.id]
                node.func = ast.Name(id=replacement, ctx=ast.Load())
            elif isinstance(node.func, ast.Attribute):
                if isinstance(node.func.value, ast.Name) and node.func.value.id in type_map:
                    replacement: str = type_map[node.func.value.id]
                    # 指针类型参数（如 list[AST | t.CPtr] 中的 T）在表达式上下文中
                    # 需替换为 BinOp(AST | t.CPtr)，使 __sizeof__ 等处理器能正确识别
                    # 指针语义并直接返回 8，避免触发 struct 加载和重入编译
                    if cptr_params and node.func.value.id in cptr_params:
                        node.func.value = ast.BinOp(
                            left=self._make_name_node(replacement),
                            op=ast.BitOr(),
                            right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load())
                        )
                    else:
                        node.func.value = ast.Name(id=replacement, ctx=ast.Load())
                else:
                    self._apply_type_map_to_expr(node.func.value, type_map, cptr_params)
            for arg in node.args:
                self._apply_type_map_to_expr(arg, type_map, cptr_params)
        elif isinstance(node, ast.Attribute):
            if isinstance(node.value, ast.Name) and node.value.id in type_map:
                replacement: str = type_map[node.value.id]
                if cptr_params and node.value.id in cptr_params:
                    node.value = ast.BinOp(
                        left=self._make_name_node(replacement),
                        op=ast.BitOr(),
                        right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load())
                    )
                else:
                    node.value = ast.Name(id=replacement, ctx=ast.Load())
            else:
                self._apply_type_map_to_expr(node.value, type_map, cptr_params)
        elif isinstance(node, ast.BinOp):
            self._apply_type_map_to_expr(node.left, type_map, cptr_params)
            self._apply_type_map_to_expr(node.right, type_map, cptr_params)
        elif isinstance(node, ast.UnaryOp):
            self._apply_type_map_to_expr(node.operand, type_map, cptr_params)
        elif isinstance(node, ast.Compare):
            self._apply_type_map_to_expr(node.left, type_map, cptr_params)
            for comp in node.comparators:
                self._apply_type_map_to_expr(comp, type_map, cptr_params)
        elif isinstance(node, ast.BoolOp):
            for val in node.values:
                self._apply_type_map_to_expr(val, type_map, cptr_params)
        elif isinstance(node, ast.IfExp):
            self._apply_type_map_to_expr(node.test, type_map, cptr_params)
            self._apply_type_map_to_expr(node.body, type_map, cptr_params)
            self._apply_type_map_to_expr(node.orelse, type_map, cptr_params)
        elif isinstance(node, ast.Subscript):
            self._apply_type_map_to_expr(node.value, type_map, cptr_params)
            self._apply_type_map_to_expr(node.slice, type_map, cptr_params)
        elif isinstance(node, ast.Name):
            if node.id in type_map:
                node.id = type_map[node.id]

    def _infer_type_arg_from_value(self, val: ir.Value, Gen: LlvmCodeGenerator) -> str:
        if val is None:
            return 'int'
        if isinstance(val.type, ir.IntType):
            if val.type.width == 64:
                return 'i64'
            elif val.type.width == 16:
                return 'i16'
            elif val.type.width == 8:
                return 'i8'
            return 'int'
        elif isinstance(val.type, ir.DoubleType):
            return 'double'
        elif isinstance(val.type, ir.FloatType):
            return 'float'
        elif isinstance(val.type, ir.PointerType):
            return 'void*'
        return 'int'

    def _specialize_generic_function(self, FuncName: str, type_args: list[str], Gen: LlvmCodeGenerator) -> str | None:
        if not hasattr(self, '_generic_templates') or FuncName not in self._generic_templates:
            return None
        template: dict[str, Any] = self._generic_templates[FuncName]
        Node: ast.FunctionDef = template['node']
        type_param_names: list[str] = template['type_params']
        ClassName: str | None = template['class_name']
        if len(type_args) != len(type_param_names):
            return None
        spec_key: str = FuncName + '<' + ','.join(type_args) + '>'
        if not hasattr(self, '_generic_specializations'):
            self._generic_specializations = {}
        if spec_key in self._generic_specializations:
            return self._generic_specializations[spec_key]
        has_cexport: bool = False
        if Node.returns:
            try:
                RetTypeInfo: Any = None
                if isinstance(Node.returns, ast.BinOp) and isinstance(Node.returns.op, ast.BitOr):
                    RetTypeInfo = self.Trans.TypeMergeHandler.MergeTypes(Node.returns)
                else:
                    RetTypeInfo = CTypeInfo.FromNode(Node.returns, self.Trans.SymbolTable)
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExport):
                    has_cexport = True
            except Exception as _e:
                if _config_mode == "strict":
                    self.Trans.LogWarning(f"异常被忽略: {_e}")
        spec_name: str = self._mangle_generic_name(FuncName, type_args, has_cexport)
        type_map: dict[str, str] = {}
        for i, tp_name in enumerate(type_param_names):
            type_map[tp_name] = type_args[i]
        SpecNode: ast.FunctionDef = copy.deepcopy(Node)
        SpecNode.type_params = []
        SpecNode.name = spec_name
        self._apply_type_map_to_node(SpecNode, type_map)
        if has_cexport:
            if not hasattr(Gen, '_export_funcs'):
                Gen._export_funcs = set()
            Gen._export_funcs.add(spec_name)
        saved_builder: Any = Gen.builder
        saved_variables: dict[str, Any] = dict(Gen.variables) if Gen.variables else {}
        saved_direct_values: dict[str, Any] = dict(Gen._direct_values) if Gen._direct_values else {}
        saved_var_type_info: dict[str, Any] = dict(Gen.var_type_info) if Gen.var_type_info else {}
        saved_var_signedness: dict[str, Any] = dict(Gen.var_signedness) if Gen.var_signedness else {}
        saved_global_vars: set[str] = set(Gen.global_vars) if Gen.global_vars else set()
        saved_var_scopes: list[dict[str, Any]] = [dict(s) for s in self.Trans.VarScopes] if self.Trans.VarScopes else []
        saved_func: Any = Gen.func
        saved_current_func_name: str | None = getattr(Gen, '_current_func_name', None)
        saved_block: Any = None
        if Gen.builder and Gen.builder.block and not Gen.builder.block.is_terminated:
            saved_block = Gen.builder.block
        self._EmitFunctionForwardDeclLlvm(SpecNode, Gen, ClassName=ClassName)
        self._EmitFunctionLlvm(SpecNode, Gen, ClassName=ClassName)
        Gen.builder = saved_builder
        if saved_block is not None and Gen.builder is not None:
            Gen.builder.position_at_end(saved_block)
        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
        Gen.func = saved_func
        if saved_current_func_name is not None:
            Gen._current_func_name = saved_current_func_name
        self.Trans.VarScopes = saved_var_scopes
        self._generic_specializations[spec_key] = spec_name
        if not hasattr(self.Trans, '_generic_specializations'):
            self.Trans._generic_specializations = {}
        self.Trans._generic_specializations[spec_key] = spec_name
        return spec_name

    def _EmitFunctionForwardDeclLlvm(self, Node: ast.FunctionDef, Gen: LlvmCodeGenerator, ClassName: str | None = None) -> None:
        if self._is_generic_function(Node):
            if not hasattr(self, '_generic_templates'):
                self._generic_templates = {}
            RawFuncName: str = Node.name
            if ClassName:
                FuncName: str = f"{ClassName}.{RawFuncName}"
            else:
                FuncName = RawFuncName
            type_params: list[str] = [tp.name for tp in Node.type_params]
            self._generic_templates[FuncName] = {
                'node': Node,
                'type_params': type_params,
                'class_name': ClassName,
            }
            return
        result: Any = self._GetFunctionSignatureLlvm(Node, Gen, ClassName)
        if result is None:
            return
        FuncName: str
        FuncType: ir.FunctionType
        ReturnTypeInfo: Any
        ParamTypeStrs: list[Any]
        CReturnTypes: list[ast.AST]
        IsMethod: bool
        ResolvedClassName: str | None
        IsVariadic: bool
        FuncName, FuncType, ReturnTypeInfo, ParamTypeStrs, CReturnTypes, IsMethod, ResolvedClassName, IsVariadic = result
        IsUserMarkedExport: bool = False
        if Node.returns:
            try:
                RetTypeInfo: Any = None
                RetTypeInfo = self.ResolveAnnotationType(Node.returns)
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExport) and not RetTypeInfo.IsState:
                    Gen._export_funcs.add(FuncName)
                    IsUserMarkedExport = True
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExtern):
                    Gen._export_funcs.add(FuncName)
                    IsUserMarkedExport = True
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.IsState:
                    Gen._export_funcs.add(FuncName)  # t.State 标记的函数必须保持原始名称，以便链接器解析
                    IsUserMarkedExport = True
            except Exception as _e:
                if _config_mode == "strict":
                    self.Trans.LogWarning(f"异常被忽略: {_e}")
        # 装饰器形式的存储类标记（@t.CExport / @t.CExtern / @t.State 等）
        deco_flags: dict[str, bool] = self._extract_decorator_storage_flags(Node)
        if deco_flags['is_export'] or deco_flags['is_extern'] or deco_flags['is_state']:
            Gen._export_funcs.add(FuncName)
            IsUserMarkedExport = True
        # 注册当前模块定义的函数名，使 _mangle_func_name 跳过 _export_extern_funcs 检查
        # （_export_extern_funcs 是跨模块共享集合，包含所有 CExtern 函数名；当前模块定义的
        # 同名用户函数应使用 SHA1 前缀，而非被误判为外部 C 函数返回裸名）
        Gen._current_module_func_names.add(FuncName)
        # 移除导入污染：用户函数未显式标记导出，但名称在 _export_funcs 中（来自导入的同名 C 库函数）
        if not IsUserMarkedExport and FuncName in Gen._export_funcs:
            Gen._export_funcs.discard(FuncName)
        MangledName: str = Gen._mangle_func_name(FuncName)
        need_new: bool = MangledName not in Gen.functions
        if not need_new:
            existing: Any = Gen.functions[MangledName]
            if getattr(existing, 'name', MangledName) != MangledName:
                need_new = True
        if need_new:
            try:
                func: ir.Function = ir.Function(Gen.module, FuncType, name=MangledName)
                func.attributes.add('noredzone')
                if hasattr(self, '_cdefine_funcs') and FuncName in self._cdefine_funcs:
                    func.linkage = 'linkonce_odr'
                    func.attributes.add('alwaysinline')
                if hasattr(self, '_pending_llvm_attrs') and FuncName in self._pending_llvm_attrs:
                    for attr_name in self._pending_llvm_attrs[FuncName]:
                        try:
                            func.attributes.add(attr_name)
                        except Exception as _e:
                            if _config_mode == "strict":
                                raise
                            _vlog().warning(f"添加函数属性失败: {_e}", "Exception")
                Gen.functions[MangledName] = func
                if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
                    Gen.functions[FuncName] = func
            except Exception as _e:
                if _config_mode == "strict":
                    self.Trans.LogWarning(f"异常被忽略: {_e}")
        else:
            existing = Gen.functions[MangledName]
            existing_type: ir.FunctionType | None = getattr(existing, 'ftype', None)
            if existing_type and existing_type != FuncType:
                Gen.functions[MangledName] = self._replace_function_decl(Gen, FuncName, FuncType)
                if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
                    Gen.functions[FuncName] = Gen.functions[MangledName]
            elif not existing_type:
                try:
                    Gen.functions[MangledName] = self._replace_function_decl(Gen, FuncName, FuncType)
                    if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
                        Gen.functions[FuncName] = Gen.functions[MangledName]
                except Exception as _e:
                    if _config_mode == "strict":
                        self.Trans.LogWarning(f"异常被忽略: {_e}")
        self.Trans.FunctionDefCache[FuncName] = Node

    def _replace_function_decl(self, Gen: LlvmCodeGenerator, FuncName: str, NewFuncType: ir.FunctionType) -> ir.Function:
        MangledName: str = Gen._mangle_func_name(FuncName)
        old_func: Any = Gen.functions.get(MangledName)
        if old_func is None:
            try:
                return ir.Function(Gen.module, NewFuncType, name=MangledName)
            except Exception:  # 回退：函数已存在时返回旧函数
                return old_func
        try:
            old_name: str = old_func.name
            if old_name in getattr(Gen.module, 'globals', {}):
                del Gen.module.globals[old_name]
            module_scope: Any = getattr(Gen.module, 'scope', None)
            if getattr(module_scope, '_useset', None):
                module_scope._useset.discard(old_name)
            if getattr(Gen.module, '_guessed_names', None):
                Gen.module._guessed_names.discard(FuncName)
            new_func: ir.Function = ir.Function(Gen.module, NewFuncType, name=MangledName)
            Gen.functions[MangledName] = new_func
            if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
                Gen.functions[FuncName] = new_func
            return new_func
        except Exception as ex:
            traceback.print_exc()
            Gen.functions[MangledName] = old_func
            if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
                Gen.functions[FuncName] = old_func
            return old_func

    def _EmitFunctionLlvm(self, Node: ast.FunctionDef, Gen: LlvmCodeGenerator, ClassName: str | None = None, extra_params: list[tuple[str, ir.Type]] | None = None) -> ir.Function | None:
        if self._is_generic_function(Node):
            return
        FuncName, RawFuncName, func_meta = self._compute_func_name_meta(Node, ClassName)
        # 保存父级 _CurrentCpythonObjectClass，防止嵌套函数发射污染父方法类上下文
        # （例如 HandleImport body 内触发 list[ast.ASTptr] 方法发射，结束后会清空 _CurrentCpythonObjectClass）
        saved_cpython_class: str | None = self.Trans._CurrentCpythonObjectClass
        CReturnTypes = []
        IsPtr = False
        fn_attrs = {}
        # 自定义行为装饰器列表，用于生成 wrapper 函数
        # 任何 @name 或 @name(args) 只要不是内置装饰器，都视为自定义行为装饰器
        behavior_decorators = []
        # 内置装饰器名称，这些由编译器特殊处理，不作为行为装饰器
        _BUILTIN_DECORATORS = {'staticmethod', 'property', 'classmethod'}
        _symtab: object = self.Trans.SymbolTable
        if Node.decorator_list:
            for decorator in Node.decorator_list:
                # 跳过 t 模块存储类标记装饰器（@t.CExport / @CExport 等）
                if self._is_t_storage_decorator(decorator, _symtab):
                    continue
                # 识别自定义行为装饰器：@name（ast.Name 形式）
                if isinstance(decorator, ast.Name):
                    if decorator.id not in _BUILTIN_DECORATORS:
                        behavior_decorators.append({'name': decorator.id, 'args': [], 'kwargs': {}})
                        continue
                # 识别带参数的自定义行为装饰器：@name(arg1, key=val)（ast.Call + ast.Name 形式）
                if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Name):
                    deco_name = decorator.func.id
                    if deco_name not in _BUILTIN_DECORATORS:
                        deco_info = {'name': deco_name, 'args': [], 'kwargs': {}}
                        for arg in decorator.args:
                            if isinstance(arg, ast.Constant):
                                deco_info['args'].append(arg.value)
                        for kw in decorator.keywords:
                            if isinstance(kw.value, ast.Constant):
                                deco_info['kwargs'][kw.arg] = kw.value.value
                        behavior_decorators.append(deco_info)
                        continue
                if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
                    if decorator.func.attr == 'CReturn':
                        for arg in decorator.args:
                            CReturnTypes.append(arg)
                    elif decorator.func.attr == 'Attribute' and isinstance(decorator.func.value, ast.Name) and decorator.func.value.id == 'c':
                        for arg in decorator.args:
                            if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Attribute):
                                if isinstance(arg.func.value, ast.Attribute) and isinstance(arg.func.value.value, ast.Name) and IsTModule(arg.func.value.value.id, self.Trans.SymbolTable) and arg.func.value.attr == 'attr':
                                    attr_name = arg.func.attr
                                    str_args = [a.value for a in arg.args if isinstance(a, ast.Constant) and isinstance(a.value, str)]
                                    int_args = [a.value for a in arg.args if isinstance(a, ast.Constant) and isinstance(a.value, int)]
                                    if attr_name == 'section' and str_args:
                                        fn_attrs['section'] = str_args[0]
                                    elif attr_name == 'aligned' and int_args:
                                        fn_attrs['aligned'] = int_args[0]
                                    elif attr_name == 'visibility' and str_args:
                                        fn_attrs['visibility'] = str_args[0]
                                    elif attr_name in ('noreturn', 'always_inline', 'noinline', 'cold', 'hot', 'constructor', 'destructor', 'pure', 'const', 'malloc', 'returns_nonnull', 'used', 'naked', 'no_instrument_function', 'warn_unused_result', 'weak', 'fallthrough'):
                                        if not arg.args:
                                            fn_attrs[attr_name] = True
                                elif isinstance(arg.func.value, ast.Attribute) and arg.func.value.attr == 'llvm' and isinstance(arg.func.value.value, ast.Attribute) and arg.func.value.value.attr == 'attr' and isinstance(arg.func.value.value.value, ast.Name) and IsTModule(arg.func.value.value.value.id, self.Trans.SymbolTable):
                                    llvm_attr_name = arg.func.attr
                                    if llvm_attr_name in self._LLVM_ATTR_NAMES:
                                        fn_attrs[f'llvm.{llvm_attr_name}'] = True
                            elif isinstance(arg, ast.Attribute):
                                if isinstance(arg.value, ast.Attribute) and isinstance(arg.value.value, ast.Name) and IsTModule(arg.value.value.id, self.Trans.SymbolTable) and arg.value.attr == 'attr':
                                    attr_name = arg.attr
                                    if attr_name in ('noreturn', 'always_inline', 'noinline', 'cold', 'hot', 'constructor', 'destructor', 'pure', 'const', 'malloc', 'returns_nonnull', 'used', 'naked', 'no_instrument_function', 'warn_unused_result', 'weak', 'fallthrough', 'packed'):
                                        fn_attrs[attr_name] = True
                                elif isinstance(arg.value, ast.Attribute) and arg.value.attr == 'llvm' and isinstance(arg.value.value, ast.Attribute) and arg.value.value.attr == 'attr' and isinstance(arg.value.value.value, ast.Name) and IsTModule(arg.value.value.value.id, self.Trans.SymbolTable):
                                    llvm_attr_name = arg.attr
                                    if llvm_attr_name in self._LLVM_ATTR_NAMES:
                                        fn_attrs[f'llvm.{llvm_attr_name}'] = True
        # 检查 @t.TLS 装饰器（一次性初始化标记）
        is_tls_func: bool = False
        if Node.decorator_list:
            for decorator in Node.decorator_list:
                if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name):
                    if IsTModule(decorator.value.id, _symtab) and decorator.attr == 'TLS':
                        is_tls_func = True
                        break
                elif isinstance(decorator, ast.Name) and decorator.id == 'TLS' and hasattr(t, 'TLS'):
                    is_tls_func = True
                    break
        if Node.returns:
            if isinstance(Node.returns, ast.Subscript) and isinstance(Node.returns.value, ast.Name) and Node.returns.value.id == 'tuple':
                slice_node = Node.returns.slice
                if isinstance(slice_node, ast.Tuple):
                    for elt in slice_node.elts:
                        CReturnTypes.append(elt)
                else:
                    CReturnTypes.append(slice_node)
        
        # 先强制检查 str 类型注解
        is_str_return = False
        ReturnTypeInfo = None
        if Node.returns:
            if isinstance(Node.returns, ast.Name) and Node.returns.id in ('str', 'bytes'):
                is_str_return = True
            else:
                try:
                    rt_info = CTypeInfo.FromNode(Node.returns, self.Trans.SymbolTable)
                    if rt_info and rt_info.IsStr:
                        is_str_return = True
                except Exception as _e:
                    if _config_mode == "strict":
                        self.Trans.LogWarning(f"异常被忽略: {_e}")
        
        if is_str_return:
            ReturnTypeInfo = CTypeInfo()
            ReturnTypeInfo.BaseType = t.CChar()
            ReturnTypeInfo.PtrCount = 1
        elif Node.returns:
            if CReturnTypes:
                ReturnTypeInfo = CTypeInfo()
                ReturnTypeInfo.BaseType = t.CVoid()
            else:
                try:
                    if isinstance(Node.returns, ast.BinOp) and isinstance(Node.returns.op, ast.BitOr):
                        ReturnTypeInfo = getattr(self.Trans, 'TypeMergeHandler', None) and self.Trans.TypeMergeHandler.MergeTypes(Node.returns)
                        if not isinstance(ReturnTypeInfo, CTypeInfo):
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CVoid()
                        if (ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState) or ReturnTypeInfo.PtrCount >= 2:
                            def _FindNonVoidCTypeInfo(node):
                                if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
                                    results = []
                                    for child in [node.left, node.right]:
                                        r = _FindNonVoidCTypeInfo(child)
                                        if r and not r.IsVoid:
                                            results.append(r)
                                    for r in results:
                                        if not r.IsPtr and not r.IsStruct:
                                            return r
                                    return results[0] if results else None
                                try:
                                    SideInfo = CTypeInfo.FromNode(node, self.Trans.SymbolTable)
                                    if SideInfo:
                                        return SideInfo
                                except Exception as _e:
                                    if _config_mode == "strict":
                                        self.Trans.LogWarning(f"异常被忽略: {_e}")
                                return None
                            found = _FindNonVoidCTypeInfo(Node.returns)
                            if found and not found.IsVoid:
                                ReturnTypeInfo = found
                        if ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CInt()
                    else:
                        is_str_type = False
                        if isinstance(Node.returns, ast.Name) and Node.returns.id in ('str', 'bytes'):
                            is_str_type = True
                        ReturnTypeInfo = CTypeInfo.FromNode(Node.returns, self.Trans.SymbolTable)
                        if ReturnTypeInfo and ReturnTypeInfo.IsDefine:
                            inferred = self._infer_return_type_from_body(Node, Gen, ClassName)
                            if inferred:
                                ReturnTypeInfo = CTypeInfo.FromTypeName(inferred[0])
                                ReturnTypeInfo.PtrCount = 1 if inferred[1] else 0
                            else:
                                ReturnTypeInfo = CTypeInfo()
                                ReturnTypeInfo.BaseType = t.CInt()
                            if not hasattr(self, '_cdefine_funcs'):
                                self._cdefine_funcs = set()
                            self._cdefine_funcs.add(FuncName)
                        elif ReturnTypeInfo and ReturnTypeInfo.IsState:
                            pass  # t.State is a modifier, preserve the actual return type
                        if ReturnTypeInfo is None:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CVoid()
                        if is_str_type or ReturnTypeInfo.IsStr:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CChar()
                            ReturnTypeInfo.PtrCount = 1
                        # 检查泛型类返回类型 (如 list[str])
                        # 注意：_from_node_subscript 对未识别的泛型下标（如 list[str]）返回空 CTypeInfo（BaseType=None），
                        # 此时 IsVoid 为 False（因为 IsVoid 仅检查 t.CVoid 实例），需额外检测 BaseType is None
                        if (isinstance(Node.returns, ast.Subscript)
                            and isinstance(Node.returns.value, ast.Name)
                            and hasattr(self.Trans.ClassHandler, '_generic_class_templates')
                            and Node.returns.value.id in self.Trans.ClassHandler._generic_class_templates
                            and (ReturnTypeInfo.IsVoid or ReturnTypeInfo.BaseType is None) and ReturnTypeInfo.PtrCount == 0):
                            ret_class: str = Node.returns.value.id
                            ret_slice: ast.AST = Node.returns.slice
                            ret_type_args: list[str] = []
                            ret_type_names: list[str] = []
                            if isinstance(ret_slice, ast.Tuple):
                                for elt in ret_slice.elts:
                                    if isinstance(elt, ast.Name):
                                        tn2: str = elt.id
                                        ts2: str = tn2
                                        if tn2 == 'int':
                                            ts2, tn2 = 'int', 'CInt'
                                        ret_type_args.append(ts2)
                                        ret_type_names.append(tn2)
                            elif isinstance(ret_slice, ast.Name):
                                tn2: str = ret_slice.id
                                ts2: str = tn2
                                if tn2 == 'int':
                                    ts2, tn2 = 'int', 'CInt'
                                ret_type_args.append(ts2)
                                ret_type_names.append(tn2)
                            # 返回类型解析只需 struct 定义，不需方法体；使用 declare_only=True
                            # 避免过早触发完整特化（此时 MemManager.alloc 可能尚未注册，
                            # 导致 __new__ 的 pool.alloc(48) 解析失败，IR 块未终止）。
                            spec_name2: str | None = self.Trans.ClassHandler._specialize_generic_class(
                                ret_class, ret_type_args, Gen, type_names=ret_type_names, declare_only=True)
                            if spec_name2 and spec_name2 in Gen.structs:
                                ReturnTypeInfo = CTypeInfo()
                                ReturnTypeInfo.BaseType = t.CStruct(name=spec_name2)
                                ReturnTypeInfo.PtrCount = 1
                        if (ReturnTypeInfo.IsVoid or ReturnTypeInfo.BaseType is None) and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState:
                            ReturnTypeInfo = CTypeInfo()
                            ReturnTypeInfo.BaseType = t.CInt()
                except Exception:  # 回退：设置默认返回类型为 CInt
                    ReturnTypeInfo = CTypeInfo()
                    ReturnTypeInfo.BaseType = t.CInt()
        else:
            ReturnTypeInfo = CTypeInfo()
            ReturnTypeInfo.BaseType = t.CInt()
            inferred = self._infer_return_type_from_body(Node, Gen, ClassName)
            if inferred:
                ReturnTypeInfo = CTypeInfo.FromTypeName(inferred[0])
                ReturnTypeInfo.PtrCount = 1 if inferred[1] else 0
        
        ReturnType = Gen._ctype_to_llvm(ReturnTypeInfo)

        if isinstance(ReturnType, ir.VoidType) and FuncName == 'main':
            ReturnType = ir.IntType(32)
        IsMethod, IsClassMethod, ResolvedClassName = self._resolve_method_class(Node, ClassName, func_meta, FuncName, Gen)
        # __new__ methods should return a pointer to the struct (for heap allocation replacement)
        if RawFuncName == '__new__' and ResolvedClassName:
            StructType = Gen.structs.get(ResolvedClassName)
            if StructType:
                if isinstance(StructType, ir.PointerType):
                    ReturnType = StructType
                else:
                    ReturnType = ir.PointerType(StructType)
        ParamTypes = []
        ParamNames = []
        ParamTypeStrs = []
        auto_addr_modes_emit: list[str | None] = []
        self.Trans.VarScopes.append({})
        for Arg in Node.args.args:
            ParamIsUnsigned = False
            if Arg.annotation:
                try:
                    ParamTypeInfo = self.ResolveAnnotationType(Arg.annotation)
                    if ParamTypeInfo is None:
                        ParamTypeInfo = CTypeInfo()
                        ParamTypeInfo.BaseType = t.CInt()
                    IsPtr = ParamTypeInfo.IsPtr
                    if ParamTypeInfo and getattr(ParamTypeInfo, 'IsCpythonObject', False) and not IsPtr:
                        IsPtr = True
                        ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1)
                    if ParamTypeInfo.IsStr or (isinstance(Arg.annotation, ast.Name) and Arg.annotation.id in ('str', 'bytes')):
                        ParamTypeInfo = CTypeInfo()
                        ParamTypeInfo.BaseType = t.CChar()
                        ParamTypeInfo.PtrCount = 1
                        IsPtr = True
                    # C 语言中数组参数退化为指针：list[type, N] → type*
                    if ParamTypeInfo.ArrayDims:
                        ParamTypeInfo.ArrayDims = []
                        ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1)
                    ParamType = Gen._ctype_to_llvm(ParamTypeInfo)
                    if ParamTypeInfo and ParamTypeInfo.IsFuncPtr:
                        ParamType = ir.IntType(8).as_pointer()
                    ParamIsUnsigned = ParamTypeInfo.IsUInt
                except Exception:  # 回退：参数类型解析失败时使用默认 i32
                    ParamType = ir.IntType(32)
                    ParamTypeInfo = CTypeInfo()
                    ParamTypeInfo.BaseType = t.CInt()
            else:
                ParamType = ir.IntType(32)
                ParamTypeInfo = CTypeInfo()
                ParamTypeInfo.BaseType = t.CInt()
            ParamTypes.append(ParamType)
            ParamNames.append(Arg.arg)
            ParamTypeStrs.append(ParamTypeInfo)
            # 检测 t.CNeedPtr / t.CAutoPtr 参数注解
            auto_mode_emit: str | None = None
            if ParamTypeInfo is not None and hasattr(ParamTypeInfo, 'BaseType') and ParamTypeInfo.BaseType is not None:
                if isinstance(ParamTypeInfo.BaseType, t.CAutoPtr):
                    auto_mode_emit = 'always'
                elif isinstance(ParamTypeInfo.BaseType, t.CNeedPtr):
                    auto_mode_emit = 'need'
            auto_addr_modes_emit.append(auto_mode_emit)
            Gen._record_var_signedness(Arg.arg, ParamIsUnsigned)
            self.Trans.VarScopes[-1][Arg.arg] = ParamTypeInfo
            if Arg.annotation:
                try:
                    PInfo = self.ResolveAnnotationType(Arg.annotation)
                    if PInfo and (PInfo.DataConst or PInfo.VarConst):
                        Gen.var_const_flags[Arg.arg] = True
                except Exception as _e:
                    if _config_mode == "strict":
                        self.Trans.LogWarning(f"异常被忽略: {_e}")
        if CReturnTypes:
            CReturnLlvmTypes = []
            for i, ReturnTypeNode in enumerate(CReturnTypes):
                ReturnTypeInfo = CTypeInfo.FromNode(ReturnTypeNode, self.Trans.SymbolTable)
                if ReturnTypeInfo and ReturnTypeInfo.IsStr:
                    ReturnTypeInfo = CTypeInfo()
                    ReturnTypeInfo.BaseType = t.CChar()
                    ReturnTypeInfo.PtrCount = 1
                if ReturnTypeInfo is None:
                    ReturnTypeInfo = CTypeInfo()
                    ReturnTypeInfo.BaseType = t.CInt()
                RetType = Gen._ctype_to_llvm(ReturnTypeInfo)
                CReturnLlvmTypes.append(RetType)
            ReturnType = ir.LiteralStructType(CReturnLlvmTypes)
            self.Trans.CurrentCReturnTypes = CReturnTypes
        else:
            self.Trans.CurrentCReturnTypes = None
        self._apply_struct_self_cls_types(ParamTypes, ParamNames, IsMethod, IsClassMethod, ResolvedClassName, Gen)
        IsVariadic = Node.args.vararg is not None
        if extra_params:
            for var_name, ptr_type in extra_params:
                ParamTypes.append(ptr_type)
                ParamNames.append(f'__nonlocal_{var_name}__')
        HasStopIterFlag = False
        if IsMethod and RawFuncName == '__next__':
            ParamTypes.append(ir.PointerType(ir.IntType(1)))
            ParamNames.append('__stop_iter_flag__')
            HasStopIterFlag = True
        HasRaise = self._body_contains_raise(Node.body)
        if HasRaise and RawFuncName != 'main':
            ParamTypes.append(ir.PointerType(ir.PointerType(ir.IntType(8))))
            ParamNames.append('__eh_msg_out__')
            ParamTypes.append(ir.PointerType(ir.IntType(32)))
            ParamNames.append('__eh_code_out__')
        FuncType = ir.FunctionType(ReturnType, ParamTypes, var_arg=IsVariadic)
        # 存储 auto_addr_modes（为额外参数补 None）
        total_params_emit: int = len(ParamTypes)
        while len(auto_addr_modes_emit) < total_params_emit:
            auto_addr_modes_emit.append(None)
        Gen._auto_addr_params[FuncName] = auto_addr_modes_emit
        self.Trans.FunctionDefCache[FuncName] = Node
        IsInlineFunc = False
        IsExternFunc = False
        IsStateFunc = False
        IsUserMarkedExport: bool = False
        if Node.returns:
            try:
                RetTypeInfo = None
                RetTypeInfo = self.ResolveAnnotationType(Node.returns)
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CInline):
                    IsInlineFunc = True
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExport) and not RetTypeInfo.IsState:
                    Gen._export_funcs.add(FuncName)
                    IsUserMarkedExport = True
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExtern):
                    IsExternFunc = True
                    Gen._export_funcs.add(FuncName)
                    IsUserMarkedExport = True
                if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.IsState:
                    IsStateFunc = True
                    Gen._export_funcs.add(FuncName)  # 外部 C 函数声明必须保持原始名称
                    IsUserMarkedExport = True
            except Exception as _e:
                if _config_mode == "strict":
                    self.Trans.LogWarning(f"异常被忽略: {_e}")
        # 装饰器形式的存储类标记（@t.CExport / @t.CExtern / @t.CStatic / @t.State / @t.CInline）
        deco_flags: dict[str, bool] = self._extract_decorator_storage_flags(Node)
        if deco_flags['is_inline']:
            IsInlineFunc = True
        if deco_flags['is_extern']:
            IsExternFunc = True
        if deco_flags['is_state']:
            IsStateFunc = True
        if deco_flags['is_export'] or deco_flags['is_extern'] or deco_flags['is_state']:
            Gen._export_funcs.add(FuncName)
            IsUserMarkedExport = True
        # 注册当前模块定义的函数名，使 _mangle_func_name 跳过 _export_extern_funcs 检查
        Gen._current_module_func_names.add(FuncName)
        # 移除导入污染：用户函数未显式标记导出，但名称在 _export_funcs 中（来自导入的同名 C 库函数）
        if not IsUserMarkedExport and FuncName in Gen._export_funcs:
            Gen._export_funcs.discard(FuncName)
        MangledName = Gen._mangle_func_name(FuncName)
        if MangledName in Gen.functions:
            func = Gen.functions[MangledName]
            if getattr(func, 'name', MangledName) != MangledName:
                func = ir.Function(Gen.module, FuncType, name=MangledName)
                Gen.functions[MangledName] = func
            else:
                existing_type = getattr(func, 'ftype', None)
                if existing_type and existing_type != FuncType:
                    func = self._replace_function_decl(Gen, FuncName, FuncType)
        else:
            func = ir.Function(Gen.module, FuncType, name=MangledName)
            Gen.functions[MangledName] = func
        if MangledName == FuncName or FuncName not in Gen._export_extern_funcs:
            Gen.functions[FuncName] = func
        func.attributes.add('noredzone')
        if IsInlineFunc:
            func.linkage = 'linkonce_odr'
            func.attributes.add('alwaysinline')
        if hasattr(self, '_cdefine_funcs') and FuncName in self._cdefine_funcs:
            func.linkage = 'linkonce_odr'
            func.attributes.add('alwaysinline')
        if fn_attrs:
            _LLVM_FN_ATTR_MAP = {
                'noreturn': 'noreturn',
                'always_inline': 'alwaysinline',
                'noinline': 'noinline',
                'cold': 'cold',
                'hot': 'hot',
                'constructor': 'constructor',
                'destructor': 'destructor',
                'malloc': 'malloc',
                'returns_nonnull': 'returns_nonnull',
                'used': 'used',
                'naked': 'naked',
                'no_instrument_function': 'no_instrument_function',
                'warn_unused_result': 'warn_unused_result',
                'fallthrough': 'fallthrough',
                'pure': 'readonly',
                'const': 'readnone',
            }
            if 'section' in fn_attrs:
                func.section = fn_attrs['section']
            if 'visibility' in fn_attrs:
                func.linkage = 'internal'
                func.attributes.add('visibility')
            if fn_attrs.get('weak'):
                func.linkage = 'weak'
            for attr_name, llvm_name in _LLVM_FN_ATTR_MAP.items():
                if fn_attrs.get(attr_name):
                    try:
                        func.attributes.add(llvm_name)
                    except Exception as _e:
                        if _config_mode == "strict":
                            raise
                        _vlog().warning(f"添加函数属性失败: {_e}", "Exception")
            for key in fn_attrs:
                if key.startswith('llvm.'):
                    llvm_attr_name = key[5:]
                    try:
                        func.attributes.add(llvm_attr_name)
                    except Exception as _e:
                        # llvmlite 不支持某些较新的 LLVM 属性（如 willreturn, mustprogress）
                        # 记录下来，后续通过 IR 后处理添加
                        if not hasattr(Gen, '_pending_str_attrs'):
                            Gen._pending_str_attrs = {}
                        Gen._pending_str_attrs.setdefault(MangledName, []).append(llvm_attr_name)
        if hasattr(self, '_pending_llvm_attrs') and FuncName in self._pending_llvm_attrs:
            for attr_name in self._pending_llvm_attrs.pop(FuncName):
                try:
                    func.attributes.add(attr_name)
                except Exception as _e:
                    # llvmlite 不支持的属性，记录下来后续通过 IR 后处理添加
                    if not hasattr(Gen, '_pending_str_attrs'):
                        Gen._pending_str_attrs = {}
                    Gen._pending_str_attrs.setdefault(MangledName, []).append(attr_name)
        # 记录自定义行为装饰器信息，供 DecoratorPass 使用
        if behavior_decorators:
            Gen._decorated_funcs[MangledName] = {
                'decorators': behavior_decorators,
                'func_name': FuncName,
                'func_type': FuncType,
                'return_type': FuncType.return_type,
                'param_types': [p.type for p in func.args],
                'param_names': ParamNames,
                'is_export': FuncName in Gen._export_funcs,
            }
        if IsExternFunc or IsStateFunc:
            return
        # 治本修复：如果函数已经有 body（blocks 不为空），跳过重复编译。
        # 否则会导致同一函数被追加第二个 entry block（llvmlite 自动重命名为 entry.1），
        # 产生非法 IR：两个 entry block + 第二个 block 无前驱成为死代码。
        # 触发场景：泛型特化路径 _EmitGenericSpecialization 先调用 _EmitFunctionForwardDeclLlvm
        # 再调用 _EmitFunctionLlvm，若特化在多个调用点被重复触发（如 list[str] 在 split/upper 等多处使用），
        # 同一 MangledName 会进入此函数两次，第二次会重复追加 entry block。
        existing_blocks: list = getattr(func, 'blocks', [])
        if existing_blocks:
            return func
        EntryBlock = func.append_basic_block(name="entry")
        Gen.builder = ir.IRBuilder(EntryBlock)
        Gen.func = func
        Gen.variables = {}
        Gen._reg_values = {}
        Gen.global_vars = set()
        if 'aligned' in fn_attrs:
            Gen._emit_stack_align(fn_attrs['aligned'])
        # 保存当前的 var_type_info，以便函数结束时恢复
        saved_var_type_info = Gen.var_type_info.copy()
        saved_var_type_assignments = Gen.var_type_assignments.copy()
        # 治本修复：保存并清空 _local_heap_ptrs / _var_to_heap_ptr。
        # 当 with 上下文中的代码（如 s1.split(',')）触发内联编译 list[str].__new__ 时，
        # 若不清空，__new__ 方法会继承外层 with 的 _local_heap_ptrs（含 %call_enter 条目），
        # 方法结束时 _emit_local_heap_frees 会尝试 bitcast/free %call_enter，
        # 但该值在 __new__ 作用域中不存在 → llc 报错 'use of undefined value'。
        saved_local_heap_ptrs = list(Gen._local_heap_ptrs)
        saved_var_to_heap_ptr = dict(Gen._var_to_heap_ptr)
        Gen._local_heap_ptrs = []
        Gen._var_to_heap_ptr = {}
        # 函数内部定义的变量会在赋值时添加到 var_type_info 中
        # 这样函数内部定义的元类型变量（如 a = t.CInt32T）就能被正确处理
        for stmt in Node.body:
            if isinstance(stmt, ast.Global):
                self.Trans.ForHandler._RegisterGlobalNames(stmt.names, Gen)
        for param, param_name in zip(func.args, ParamNames):
            param.name = param_name
            if param_name == '__stop_iter_flag__':
                Gen._stop_iter_flag_param = param
                Gen.builder.store(ir.Constant(ir.IntType(1), 0), param)
            elif param_name.startswith('__nonlocal_') and param_name.endswith('__'):
                var_name = param_name[len('__nonlocal_'):-2]
                Gen.variables[var_name] = param
            else:
                if isinstance(param.type, ir.PointerType) and isinstance(param.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                    var = Gen.builder.alloca(param.type, name=param_name)
                    Gen._store(param, var)
                    Gen.variables[param_name] = var
                    for CN, ST in Gen.structs.items():
                        if param.type.pointee == ST or (isinstance(param.type.pointee, ir.IdentifiedStructType) and isinstance(ST, ir.IdentifiedStructType) and param.type.pointee.name == ST.name):
                            Gen.var_struct_class[param_name] = CN
                            break
                elif isinstance(param.type, (ir.LiteralStructType, ir.IdentifiedStructType)):
                    var = Gen.builder.alloca(param.type, name=param_name)
                    Gen._store(param, var)
                    Gen.variables[param_name] = var
                    for CN, ST in Gen.structs.items():
                        if param.type == ST or (isinstance(param.type, ir.IdentifiedStructType) and isinstance(ST, ir.IdentifiedStructType) and param.type.name == ST.name):
                            Gen.var_struct_class[param_name] = CN
                            break
                else:
                    # 所有参数都存入 alloca，确保循环体中对参数的修改能正确反映
                    var = Gen._allocaEntry(param.type, name=param_name)
                    Gen._store(param, var)
                    Gen.variables[param_name] = var
        # 为联合类型注解（如 Function | t.CPtr）的参数设置 var_struct_class，
        # 确保编译器能正确生成 GEP 访问结构体成员（如 func.Blocks、func.Params）
        for i, arg in enumerate(Node.args.args):
            if arg.annotation and isinstance(arg.annotation, ast.BinOp) and isinstance(arg.annotation.op, ast.BitOr):
                param_name: str = ParamNames[i] if i < len(ParamNames) else arg.arg
                if param_name in Gen.variables:
                    found_struct: str | None = FindStructNameInAnnotation(arg.annotation, Gen.structs)
                    if found_struct:
                        Gen.var_struct_class[param_name] = found_struct
        if ResolvedClassName and (IsMethod or RawFuncName == '__init__'):
            self.Trans._CurrentCpythonObjectClass = ResolvedClassName
        Gen._variadic_info = None
        if IsVariadic and Node.args.vararg:
            vararg_name = getattr(Node.args.vararg, 'arg', 'args')
            last_param_name = ParamNames[-1] if ParamNames else None
            last_param_ptr = None
            for param, pn in zip(func.args, ParamNames):
                if pn == last_param_name:
                    last_param_ptr = param
                    break
            triple = getattr(Gen, 'module_triple', '') or getattr(Gen.module, 'triple', '')
            is_windows = 'windows' in triple if triple else False
            ptr_size = getattr(Gen, 'ptr_size', 8)
            # va_list 大小取决于 ABI：Windows x64 = 1个指针，Linux x64 = __va_list_tag[1]（24字节）
            # 32位平台：Windows = 4字节指针，Linux = 12字节
            if ptr_size == 4:
                va_list_size = 4 if is_windows else 12
                va_list_align = 4
            else:
                va_list_size = 8 if is_windows else 24
                va_list_align = 8 if is_windows else 16
            va_list_type = ir.ArrayType(ir.IntType(8), va_list_size)
            va_list_alloc = Gen._allocaEntry(va_list_type, name=f"{vararg_name}_va_list", align=va_list_align)
            va_list_ptr = Gen.builder.bitcast(va_list_alloc, ir.IntType(8).as_pointer(), name=f"{vararg_name}_va_list_i8ptr")
            Gen._variadic_info = {
                'vararg_name': vararg_name,
                'va_list_ptr': va_list_ptr,
                'last_param_ptr': last_param_ptr,
                'va_start_called': False,
            }
            if last_param_ptr:
                last_param_alloc = Gen._allocaEntry(last_param_ptr.type, name="last_param_copy")
                Gen.builder.store(last_param_ptr, last_param_alloc)
                Gen.emit_va_start(va_list_ptr)
                Gen._variadic_info['va_start_called'] = True
            # 用 _direct_values 注册，Name 解析时直接返回 va_list 指针（i8*），
            # 不走 variables 的 load 路径（否则会把 i8* 当 char* 加载一个字节）
            Gen._direct_values[vararg_name] = va_list_ptr
        # @t.TLS 一次性初始化检查：首次调用执行函数体，后续调用直接返回
        if is_tls_func:
            flag_name: str = f"__tls_init_done_{FuncName}"
            flag_global = None
            for gv in Gen.module.global_values:
                if gv.name == flag_name:
                    flag_global = gv
                    break
            if flag_global is None:
                flag_global = ir.GlobalVariable(Gen.module, ir.IntType(1), name=flag_name)
                flag_global.initializer = ir.Constant(ir.IntType(1), 0)
                flag_global.linkage = 'internal'
            flag_val = Gen.builder.load(flag_global, name="tls_flag_check")
            skip_bb = func.append_basic_block("tls_skip")
            cont_bb = func.append_basic_block("tls_continue")
            Gen.builder.cbranch(flag_val, skip_bb, cont_bb)
            Gen.builder.position_at_end(skip_bb)
            ActualReturnType = func.function_type.return_type
            if isinstance(ActualReturnType, ir.VoidType):
                Gen.builder.ret_void()
            elif isinstance(ActualReturnType, ir.IntType):
                Gen.builder.ret(ir.Constant(ActualReturnType, 0))
            elif isinstance(ActualReturnType, (ir.FloatType, ir.DoubleType)):
                Gen.builder.ret(ir.Constant(ActualReturnType, 0.0))
            elif isinstance(ActualReturnType, ir.PointerType):
                Gen.builder.ret(ir.Constant(ActualReturnType, None))
            else:
                Gen.builder.ret(ir.Constant(ActualReturnType, None))
            Gen.builder.position_at_end(cont_bb)
            Gen.builder.store(ir.Constant(ir.IntType(1), 1), flag_global)
        _saved_class_name = getattr(Gen, '_current_class_name', None)
        Gen._current_class_name = ClassName
        # 提取首个裸字符串字面量作为 __doc__ docstring，并跳过该节点避免生成死代码
        func_body: list[ast.stmt] = Node.body
        doc_symbol: str = f"{ClassName}.{Node.name}" if ClassName else Node.name
        if (func_body and isinstance(func_body[0], ast.Expr)
                and isinstance(func_body[0].value, ast.Constant)
                and isinstance(func_body[0].value.value, str)):
            Gen._create_doc_global(doc_symbol, func_body[0].value.value)
            func_body = func_body[1:]
        else:
            Gen._create_doc_global(doc_symbol, None)
        try:
            self.Trans.BodyHandler.HandleBodyLlvm(func_body)
        except Exception as _body_exc:
            # 方法体编译失败：确保 block 终止（防止 expected instruction opcode 错误），
            # 然后重新抛出异常让编译立即终止（不吞掉错误）
            _fn_name: str = Node.name
            _cls_name: str = ClassName if ClassName else ''
            import sys as _sys
            import traceback as _tb
            print(f"[FATAL] 方法体编译失败 ({_cls_name}.{_fn_name}): {type(_body_exc).__name__}: {_body_exc}", file=_sys.stderr)
            _tb.print_exc(file=_sys.stderr)
            if Gen.builder is not None:
                try:
                    if not Gen.builder.block.is_terminated:
                        _ret_ty = func.function_type.return_type
                        if isinstance(_ret_ty, ir.VoidType):
                            Gen.builder.ret_void()
                        elif isinstance(_ret_ty, ir.PointerType):
                            Gen.builder.ret(ir.Constant(_ret_ty, None))
                        elif isinstance(_ret_ty, ir.IntType):
                            Gen.builder.ret(ir.Constant(_ret_ty, 0))
                        else:
                            Gen.builder.ret(ir.Constant(_ret_ty, None))
                except Exception:
                    try:
                        if Gen.builder and not Gen.builder.block.is_terminated:
                            Gen.builder.ret_void()
                    except Exception:
                        pass
            raise
        if not Gen.builder.block.is_terminated:
            if 'naked' in fn_attrs:
                Gen.builder.unreachable()
                self.Trans._CurrentCpythonObjectClass = saved_cpython_class
                return
            Gen._emit_local_heap_frees()
            if Gen._variadic_info and Gen._variadic_info.get('va_start_called'):
                va_list_ptr = Gen._variadic_info.get('va_list_ptr')
                if va_list_ptr:
                    Gen.emit_va_end(va_list_ptr)
            ActualReturnType = func.function_type.return_type
            if isinstance(ActualReturnType, ir.VoidType):
                Gen.builder.ret_void()
            elif isinstance(ActualReturnType, ir.IntType):
                Gen.builder.ret(ir.Constant(ActualReturnType, 0))
            elif isinstance(ActualReturnType, (ir.FloatType, ir.DoubleType)):
                Gen.builder.ret(ir.Constant(ActualReturnType, 0.0))
            elif isinstance(ActualReturnType, ir.PointerType):
                Gen.builder.ret(ir.Constant(ActualReturnType, None))
            elif isinstance(ActualReturnType, ir.IdentifiedStructType):
                if ActualReturnType.elements:
                    zero_val = ir.Constant(ActualReturnType, [ir.Constant(et, None) if isinstance(et, (ir.PointerType, ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)) else ir.Constant(et, 0) if isinstance(et, (ir.IntType, ir.FloatType, ir.DoubleType)) else ir.Constant(et, ir.Undefined) for et in ActualReturnType.elements])
                else:
                    zero_val = ir.Constant(ActualReturnType, None)
                Gen.builder.ret(zero_val)
            elif isinstance(ActualReturnType, ir.ArrayType):
                Gen.builder.ret(ir.Constant(ActualReturnType, None))
            else:
                Gen.builder.ret_void()
        Gen.builder = None
        Gen.func = None
        Gen._current_class_name = _saved_class_name
        Gen.variables = {}
        Gen.var_signedness = {}
        Gen._reg_values = {}
        Gen._direct_values = {}
        Gen.var_struct_class = {}
        Gen.var_ptr_element = {}
        Gen.var_const_flags = {}
        # 恢复保存的 var_type_info
        Gen.var_type_info = saved_var_type_info
        Gen.var_type_assignments = saved_var_type_assignments
        Gen._stop_iter_flag_param = None
        # 恢复外层作用域的 _local_heap_ptrs / _var_to_heap_ptr
        Gen._local_heap_ptrs = saved_local_heap_ptrs
        Gen._var_to_heap_ptr = saved_var_to_heap_ptr
        Gen._variadic_info = None
        self.Trans._CurrentCpythonObjectClass = saved_cpython_class
        self.Trans.CurrentCReturnTypes = None
        if self.Trans.VarScopes:
            self.Trans.VarScopes.pop()
        self.Trans.FunctionReturnTypes[FuncName] = ReturnTypeInfo
        if not self.Trans.SymbolTable.has(FuncName):
            FuncInfo = CTypeInfo()
            FuncInfo.Name = FuncName
            FuncInfo.IsFunction = True
            FuncInfo.MetaList = func_meta
            if IsInlineFunc:
                FuncInfo.IsInline = True
                FuncInfo.InlineBody = Node.body
                FuncInfo.InlineParams = [arg.arg for arg in Node.args.args]
            self.Trans.SymbolTable.insert(FuncName, FuncInfo)
        else:
            existing = self.Trans.SymbolTable[FuncName]
            if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
                existing.MetaList = func_meta
            if IsInlineFunc:
                existing.IsInline = True
                existing.InlineBody = Node.body
                existing.InlineParams = [arg.arg for arg in Node.args.args]
        # property setter/deleter: 在原始 PropKey（不带后缀）下注册 MetaList
        if FuncMeta.PROPERTY_SETTER in func_meta or FuncMeta.PROPERTY_DELETER in func_meta:
            BasePropKey = f"{ClassName}.{RawFuncName}" if ClassName else RawFuncName
            base_existing = self.Trans.SymbolTable.lookup(BasePropKey)
            if base_existing:
                if func_meta != FuncMeta.NONE:
                    base_existing.MetaList = base_existing.MetaList | func_meta
            else:
                PropInfo = CTypeInfo()
                PropInfo.Name = BasePropKey
                PropInfo.IsFunction = True
                PropInfo.MetaList = func_meta
                self.Trans.SymbolTable.insert(BasePropKey, PropInfo)
        return func
