from __future__ import annotations
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
    from lib.core.translator import Translator
import ast
import sys
import llvmlite.ir as ir
from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta
from lib.core.VLogger import get_logger as _vlog
from lib.core.ConstEvaluator import ConstEvaluator, EvalContext
from lib.constants.config import mode as _config_mode
from lib.includes import t
from lib.includes.t import CTypeRegistry
from lib.core.SymbolUtils import IsTModule, ParseListAnnotation, AnnotationContainsName

class AssignHandle(BaseHandle):
    def __init__(self, translator: "Translator") -> None:
        super().__init__(translator)
        self._CurrentCpythonObjectClass: str | None = None

    @staticmethod
    def _contains_identified_struct(var_type: ir.Type) -> bool:
        if isinstance(var_type, ir.IdentifiedStructType):
            return True
        if isinstance(var_type, ir.ArrayType):
            return AssignHandle._contains_identified_struct(var_type.element)
        if isinstance(var_type, ir.PointerType):
            return AssignHandle._contains_identified_struct(var_type.pointee)
        if isinstance(var_type, ir.BaseStructType):
            if var_type.elements:
                return any(AssignHandle._contains_identified_struct(e) for e in var_type.elements)
        return False

    def HandleExprLlvm(self, Node: ast.expr, VarType: ir.Type | None = None) -> ir.Value | None:
        return self.Trans.ExprHandler.HandleExprLlvm(Node, VarType)

    def _HandleAssignLlvm(self, Node: ast.Assign) -> None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        Gen._set_node_info(Node, "Assign")
        if len(Node.targets) == 1:
            Target: ast.expr = Node.targets[0]
            if isinstance(Target, ast.Name):
                VarName: str = Target.id
                if VarName in Gen.var_const_flags:
                    src_info: str = Gen._get_node_info()
                    _vlog().error(f"不能对 const 变量 '{VarName}' 赋值{src_info}")
                    sys.exit(1)
                if isinstance(Node.value, ast.Attribute) and isinstance(Node.value.value, ast.Name) and IsTModule(Node.value.value.id, self.Trans.SymbolTable):
                    AttrName: str = Node.value.attr
                    Gen.var_type_info[VarName] = {'type': 't_type', 'name': AttrName}
                    Gen.var_type_assignments.setdefault(VarName, []).append({'type': 't_type', 'name': AttrName})
                    c_type_name: str = ''
                    resolved: tuple[type, int] | None = CTypeRegistry.ResolveName(AttrName)
                    if resolved is not None:
                        ctype_cls: type = resolved[0]
                        ptr_level: int = resolved[1]
                        c_type_name = CTypeRegistry.CTypeToName(ctype_cls)
                        if ptr_level > 0 and c_type_name:
                            c_type_name = c_type_name + ' *'
                    if not c_type_name:
                        if AttrName == 'CPtr':
                            c_type_name = 'void *'
                    is_unsigned: bool = Gen._is_type_unsigned(c_type_name) if c_type_name else False
                    fmt_str: str = "%u\n" if is_unsigned else "%d\n"
                    fmt_ptr: ir.Value = Gen._create_string_global(fmt_str)
                    fmt_var_name: str = f"__{VarName}_fmt"
                    if fmt_var_name not in Gen.variables:
                        fmt_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name=fmt_var_name)
                        Gen.variables[fmt_var_name] = fmt_alloca
                    Gen.builder.store(fmt_ptr, Gen.variables[fmt_var_name])
                    kind_var_name: str = f"__{VarName}_kind"
                    if kind_var_name not in Gen.variables:
                        kind_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(32), name=kind_var_name)
                        Gen.variables[kind_var_name] = kind_alloca
                    Gen.builder.store(ir.Constant(ir.IntType(32), 0), Gen.variables[kind_var_name])
                    if VarName not in Gen.variables:
                        dummy_var: ir.AllocaInstr = Gen._alloca(ir.IntType(8), name=VarName)
                        Gen.variables[VarName] = dummy_var
                    return
                if isinstance(Node.value, ast.Name) and Node.value.id in Gen.structs:
                    ClassName: str = Node.value.id
                    Gen.var_type_info[VarName] = {'type': 'class_cast', 'name': ClassName}
                    Gen.var_type_assignments.setdefault(VarName, []).append({'type': 'class_cast', 'name': ClassName})
                    fmt_str: str = "%p\n"
                    fmt_ptr: ir.Value = Gen._create_string_global(fmt_str)
                    fmt_var_name: str = f"__{VarName}_fmt"
                    if fmt_var_name not in Gen.variables:
                        fmt_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name=fmt_var_name)
                        Gen.variables[fmt_var_name] = fmt_alloca
                    Gen.builder.store(fmt_ptr, Gen.variables[fmt_var_name])
                    kind_var_name: str = f"__{VarName}_kind"
                    if kind_var_name not in Gen.variables:
                        kind_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(32), name=kind_var_name)
                        Gen.variables[kind_var_name] = kind_alloca
                    Gen.builder.store(ir.Constant(ir.IntType(32), 1), Gen.variables[kind_var_name])
                    if VarName not in Gen.variables:
                        dummy_var: ir.AllocaInstr = Gen._alloca(ir.IntType(8), name=VarName)
                        Gen.variables[VarName] = dummy_var
                    return
                if isinstance(Node.value, ast.Call) and isinstance(Node.value.func, ast.Name) and Node.value.func.id == 'va_list':
                    va_list_ptr: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(8).as_pointer(), name="va_list")
                    Gen.variables[VarName] = va_list_ptr
                    return
                IsStructCtor: bool = (isinstance(Node.value, ast.Call) and isinstance(Node.value.func, ast.Name)
                                and Node.value.func.id in Gen.structs)
                if IsStructCtor:
                    ClassName: str = Node.value.func.id
                    StructType: ir.Type = Gen.structs[ClassName]

                    IsUnion: bool = False
                    TypeInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(ClassName)
                    if TypeInfo and TypeInfo.IsUnion:
                        IsUnion = True

                    if IsUnion:
                        Value: ir.Value | None = self.HandleExprLlvm(Node.value)
                        if Value:
                            var: ir.AllocaInstr = Gen._allocaEntry(Value.type, name=VarName)
                            Gen._store(Value, var)
                            Gen.variables[VarName] = var
                        return

                    ExistingPtr: ir.Value | None = None
                    if VarName in Gen.variables and Gen.variables[VarName] is not None:
                        VarPtr: ir.Value = Gen.variables[VarName]
                        if isinstance(VarPtr.type.pointee, ir.PointerType):
                            ExistingPtr = VarPtr
                    elif VarName in Gen._reg_values:
                        OldVal: ir.Value = Gen._reg_values[VarName]
                        if isinstance(OldVal.type, ir.PointerType):
                            var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName)
                            Gen._store(OldVal, var)
                            Gen.variables[VarName] = var
                            del Gen._reg_values[VarName]
                            ExistingPtr = var
                    elif VarName in Gen._direct_values:
                        OldVal: ir.Value = Gen._direct_values.pop(VarName)
                        if isinstance(OldVal.type, ir.PointerType):
                            var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName)
                            Gen._store(OldVal, var)
                            Gen.variables[VarName] = var
                            ExistingPtr = var
                    if ExistingPtr:
                        pointee: ir.Type = ExistingPtr.type.pointee
                        # 仅当 alloca 直接存储结构体值（pointee 不是指针）时才 in-place 初始化。
                        # 当 pointee 是 PointerType 时，alloca 存储的是堆对象指针：
                        #   - 若 AnnAssign 分支未执行，alloca 内容是未初始化的栈垃圾
                        #     （可能恰好等于 pool 地址），_InitStructAtPtr 会向垃圾地址写字段 → 内存损坏
                        #   - 即使指针有效，node = Class(...) 的语义也是创建新对象并更新指针，
                        #     而非在旧对象位置 in-place 重初始化
                        # 此时必须 fall through 到通用路径 HandleExprLlvm → _HandleClassNewLlvm
                        # 以正确调用 __new__/__before_init__/__init__ 构造新对象。
                        if not isinstance(pointee, ir.PointerType) and pointee == StructType:
                            self._InitStructAtPtr(Node.value, ClassName, ExistingPtr)
                            return
                if isinstance(Node.value, ast.Attribute):
                    enum_type_name: str | None = self._CheckEnumMemberAssignment(Node.value)
                    if enum_type_name:
                        Gen.var_type_info[VarName] = {'type': 'enum', 'name': enum_type_name}
                var_type_for_list: ir.Type | None = None
                if isinstance(Node.value, ast.List) and VarName in Gen.var_type_info:
                    type_info: dict[str, str] = Gen.var_type_info[VarName]
                    if type_info.get('type') == 'CArray':
                        var_type_for_list = type_info.get('full_type')
                Value: ir.Value | None = self.HandleExprLlvm(Node.value, VarType=var_type_for_list)
                if not Value:
                    return
                if isinstance(Value.type, ir.VoidType):
                    return
                Gen._UnregisterTempPtr(Value)
                # 大端局部变量：赋值时 bswap
                Value = Gen._apply_bswap_if_big(Value, Gen.local_var_byteorders.get(VarName, ""), f"bswap_assign_{VarName}")
                if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                    found_class: str | None = None
                    found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(Value.type.pointee)
                    if found:
                        CN: str = found[0]
                        ST: ir.Type = found[1]
                        found_class = CN
                        Gen.var_struct_class[VarName] = CN
                        Gen._var_to_heap_ptr[VarName] = Value
                    if found_class is None and isinstance(Value.type.pointee, ir.IdentifiedStructType):
                        pointee_name: str = Value.type.pointee.name
                        pointee_short: str = Gen._extract_short_name(pointee_name)
                        best_elem_count: int = 0
                        for CN, ST in Gen.structs.items():
                            if isinstance(ST, ir.IdentifiedStructType):
                                st_short: str = Gen._extract_short_name(ST.name)
                                if st_short == pointee_short:
                                    elem_count: int = len(ST.elements) if ST.elements else 0
                                    if elem_count > best_elem_count:
                                        found_class = CN
                                        best_elem_count = elem_count
                        if found_class:
                            Gen.var_struct_class[VarName] = found_class
                            Gen._var_to_heap_ptr[VarName] = Value
                    # 泛型类特化触发：返回类型是泛型类特化（如 list[str]）但结构体尚未创建，
                    # 或虽然找到了结构体但它是 opaque（来自 stub 声明，尚未发射方法体）
                    _fd_struct_opaque: bool = False
                    if found_class and found_class in Gen.structs:
                        _fd_st: ir.IdentifiedStructType = Gen.structs[found_class]
                        if isinstance(_fd_st, ir.IdentifiedStructType) and (_fd_st.elements is None or len(_fd_st.elements) == 0):
                            _fd_struct_opaque = True
                    if (found_class is None or _fd_struct_opaque) and isinstance(Value.type.pointee, ir.IdentifiedStructType):
                        pn: str = Value.type.pointee.name
                        short_pn: str = pn
                        if '.' in pn:
                            pn_parts: list[str] = pn.split('.', 1)
                            if len(pn_parts[0]) >= 8 and all(c in '0123456789abcdef' for c in pn_parts[0]):
                                short_pn = pn_parts[1]
                        if '[' in short_pn and short_pn.endswith(']'):
                            gc_base: str = short_pn.split('[')[0]
                            gc_args_raw: str = short_pn[len(gc_base):]
                            gc_type_args: list[str] = []
                            for gc_arg_part in gc_args_raw.split(']['):
                                gc_arg_part = gc_arg_part.strip('[]')
                                if gc_arg_part:
                                    gc_type_args.append(gc_arg_part)
                            if (gc_type_args
                                and hasattr(self.Trans.ClassHandler, '_generic_class_templates')
                                and gc_base in self.Trans.ClassHandler._generic_class_templates):
                                gc_type_names: list[str] = []
                                for gc_ta in gc_type_args:
                                    gc_tn: str = gc_ta
                                    if gc_ta == 'int':
                                        gc_tn = 'CInt'
                                    elif gc_ta == 'double':
                                        gc_tn = 'CDouble'
                                    elif gc_ta == 'float':
                                        gc_tn = 'CFloat'
                                    elif gc_ta == 'char':
                                        gc_tn = 'CChar'
                                    elif gc_ta == 'bool':
                                        gc_tn = 'CBool'
                                    gc_type_names.append(gc_tn)
                                gc_spec: str | None = self.Trans.ClassHandler._specialize_generic_class(
                                    gc_base, gc_type_args, Gen, type_names=gc_type_names)
                                if gc_spec and gc_spec in Gen.structs:
                                    found_class = gc_spec
                                    Gen.var_struct_class[VarName] = gc_spec
                                    Gen._var_to_heap_ptr[VarName] = Value
                    else:
                        if VarName in ('mctx', 's1ctx', 's2ctx', 's5ctx'):
                            pass
                if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                    if VarName in Gen.variables and Gen.variables[VarName] is not None:
                        Gen._store(Value, Gen.variables[VarName])
                    else:
                        var: ir.AllocaInstr = Gen._allocaEntry(Value.type, name=VarName)
                        Gen._store(Value, var)
                        Gen.variables[VarName] = var
                    if isinstance(Node.value, ast.Call) and isinstance(Node.value.func, ast.Name):
                        call_func_name: str = Node.value.func.id
                        if call_func_name in Gen.var_type_info:
                            type_info: dict[str, str] = Gen.var_type_info[call_func_name]
                            if type_info['type'] in ('t_type', 'class_cast'):
                                src_fmt_var: str = f"__{call_func_name}_fmt"
                                dst_fmt_var: str = f"__{VarName}_fmt"
                                if src_fmt_var in Gen.variables:
                                    if dst_fmt_var not in Gen.variables:
                                        dst_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name=dst_fmt_var)
                                        Gen.variables[dst_fmt_var] = dst_alloca
                                    src_fmt_ptr: ir.Value = Gen._load(Gen.variables[src_fmt_var], name=f"Load_{call_func_name}_fmt_for_{VarName}")
                                    Gen.builder.store(src_fmt_ptr, Gen.variables[dst_fmt_var])
                                src_kind_var: str = f"__{call_func_name}_kind"
                                dst_kind_var: str = f"__{VarName}_kind"
                                if src_kind_var in Gen.variables:
                                    if dst_kind_var not in Gen.variables:
                                        dst_kind_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(32), name=dst_kind_var)
                                        Gen.variables[dst_kind_var] = dst_kind_alloca
                                    src_kind_val: ir.Value = Gen._load(Gen.variables[src_kind_var], name=f"Load_{call_func_name}_kind_for_{VarName}")
                                    Gen.builder.store(src_kind_val, Gen.variables[dst_kind_var])
                                Gen.var_type_info[VarName] = {'type': 't_type_runtime', 'source': call_func_name}
                    return
                if VarName in Gen.global_vars:
                    if VarName in Gen.module.globals:
                        GVar: ir.GlobalVariable = Gen.module.globals[VarName]
                        Gen._store(Value, GVar)
                        Gen.variables[VarName] = GVar
                        if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                            found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(Value.type.pointee)
                            if found:
                                CN: str = found[0]
                                ST: ir.Type = found[1]
                                Gen.var_struct_class[VarName] = CN
                    elif VarName in Gen.variables and Gen.variables[VarName] is not None:
                        Gen._store(Value, Gen.variables[VarName])
                    return
                if VarName in Gen._reg_values:
                    OldVal: ir.Value = Gen._reg_values[VarName]
                    var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName)
                    Gen._store(OldVal, var)
                    Gen.variables[VarName] = var
                    del Gen._reg_values[VarName]
                if VarName in Gen._direct_values:
                    OldVal: ir.Value = Gen._direct_values.pop(VarName)
                    var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName)
                    Gen._store(OldVal, var)
                    Gen.variables[VarName] = var
                if VarName in Gen.variables and Gen.variables[VarName] is not None:
                    VarPtr: ir.Value = Gen.variables[VarName]
                    TargetType: ir.Type | None = VarPtr.type.pointee if isinstance(VarPtr.type, ir.PointerType) else None
                    types_differ: bool
                    try:
                        types_differ = TargetType and Value.type != TargetType
                    except AssertionError:
                        types_differ = False
                    if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, ir.PointerType):
                        LoadedValue: ir.Value = Gen._load(Value, name=f"Load_{VarName}")
                        Loaded_differ: bool
                        try:
                            Loaded_differ = TargetType and LoadedValue.type != TargetType
                        except AssertionError:
                            Loaded_differ = False
                        if Loaded_differ:
                            try:
                                Coerced: ir.Value | None = Gen._coerce_value(LoadedValue, TargetType)
                                if Coerced is not None:
                                    LoadedValue = Coerced
                            except AssertionError:
                                pass
                        Gen._store(LoadedValue, VarPtr)
                    elif types_differ:
                        try:
                            Coerced: ir.Value | None = Gen._coerce_value(Value, TargetType)
                            if Coerced is not None:
                                Gen._store(Coerced, VarPtr)
                            else:
                                Gen._store(Value, VarPtr)
                        except AssertionError:
                            Gen._store(Value, VarPtr)
                    else:
                        Gen._store(Value, VarPtr)
                if VarName not in Gen.variables:
                    # 检查是否为模块级全局变量
                    # main 函数代表模块级作用域，直接修改全局变量
                    # 其他函数中，未声明 global 且未先读取的赋值创建局部变量（Python 作用域语义）
                    # 先读取过的变量已通过 HandleExprLlvm 加入 Gen.variables，会走 L289 分支存储到全局
                    CurrentFuncName: str = getattr(Gen.func, 'name', '') if Gen.func else ''
                    IsMainScope: bool = CurrentFuncName == 'main' or CurrentFuncName.endswith('.main')
                    if VarName in Gen.module.globals and (VarName in Gen.global_vars or IsMainScope):
                        GVar: ir.GlobalVariable = Gen.module.globals[VarName]
                        Gen._store(Value, GVar)
                        Gen.variables[VarName] = GVar
                    elif isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, ir.PointerType):
                        LoadedValue: ir.Value = Gen._load(Value, name=f"Load_{VarName}")
                        var: ir.AllocaInstr = Gen._allocaEntry(LoadedValue.type, name=VarName)
                        Gen._store(LoadedValue, var)
                        Gen.variables[VarName] = var
                    else:
                        var: ir.AllocaInstr = Gen._allocaEntry(Value.type, name=VarName)
                        Gen._store(Value, var)
                        Gen.variables[VarName] = var
                    is_u: bool = Gen._check_node_unsigned(Node.value)
                    Gen._record_var_signedness(VarName, 'unsigned int' if is_u else 'int')
                if isinstance(Node.value, ast.Call) and isinstance(Node.value.func, ast.Name):
                    call_func_name: str = Node.value.func.id
                    if call_func_name in Gen.var_type_info:
                        type_info: dict[str, str] = Gen.var_type_info[call_func_name]
                        if type_info['type'] in ('t_type', 'class_cast'):
                            src_fmt_var: str = f"__{call_func_name}_fmt"
                            dst_fmt_var: str = f"__{VarName}_fmt"
                            if src_fmt_var in Gen.variables:
                                if dst_fmt_var not in Gen.variables:
                                    dst_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name=dst_fmt_var)
                                    Gen.variables[dst_fmt_var] = dst_alloca
                                src_fmt_ptr: ir.Value = Gen._load(Gen.variables[src_fmt_var], name=f"Load_{call_func_name}_fmt_for_{VarName}")
                                Gen.builder.store(src_fmt_ptr, Gen.variables[dst_fmt_var])
                                src_kind_var: str = f"__{call_func_name}_kind"
                                dst_kind_var: str = f"__{VarName}_kind"
                                if src_kind_var in Gen.variables:
                                    if dst_kind_var not in Gen.variables:
                                        dst_kind_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(32), name=dst_kind_var)
                                        Gen.variables[dst_kind_var] = dst_kind_alloca
                                    src_kind_val: ir.Value = Gen._load(Gen.variables[src_kind_var], name=f"Load_{call_func_name}_kind_for_{VarName}")
                                    Gen.builder.store(src_kind_val, Gen.variables[dst_kind_var])
                                Gen.var_type_info[VarName] = {'type': 't_type_runtime', 'source': call_func_name}
                            else:
                                Gen.var_type_info[VarName] = {'type': 't_type_runtime', 'source': call_func_name}
            elif isinstance(Target, ast.Attribute):
                TargetType: ir.Type | None = None
                AttrName: str = Target.attr
                VarName: str | None = None
                if isinstance(Target.value, ast.Name):
                    VarName = Target.value.id
                if VarName:
                    ClassName: str | None = Gen.var_struct_class.get(VarName)
                    if not ClassName and Gen.global_struct_class:
                        ClassName = Gen.global_struct_class.get(VarName)
                        if ClassName:
                            Gen.var_struct_class[VarName] = ClassName
                    if not ClassName:
                        for CN in Gen.structs:
                            if VarName == CN.lower() or VarName.startswith(CN):
                                ClassName = CN
                                break
                    if ClassName and ClassName in Gen.class_members:
                        for m_name, m_type in Gen.class_members[ClassName]:
                            if m_name == AttrName:
                                TargetType = m_type
                                break
                Value: ir.Value | None = self.HandleExprLlvm(Node.value, VarType=TargetType)
                if Value:
                    self._HandleAttributeStoreLlvm(Target, Value)
            elif isinstance(Target, ast.Subscript):
                TargetType: ir.Type | None = None
                SubVarName: str | None = None
                if isinstance(Target.value, ast.Name):
                    SubVarName = Target.value.id
                    if SubVarName in Gen.var_struct_class:
                        ClassName: str = Gen.var_struct_class[SubVarName]
                        if ClassName in Gen.class_members:
                            for m_name, m_type in Gen.class_members[ClassName]:
                                if m_name == SubVarName:
                                    if isinstance(m_type, ir.PointerType):
                                        pointee: ir.Type = m_type.pointee
                                        if isinstance(pointee, ir.ArrayType):
                                            TargetType = pointee.element
                                    elif isinstance(m_type, ir.ArrayType):
                                        TargetType = m_type.element
                                    break
                if not TargetType and isinstance(Target.value, ast.Name):
                    SubVarName = Target.value.id
                    var_val: ir.Value | None = Gen.variables.get(SubVarName)
                    if var_val is None and SubVarName in Gen._direct_values:
                        var_val = Gen._direct_values[SubVarName]
                    if var_val is not None:
                        var_type: ir.Type = var_val.type
                        if isinstance(var_type, ir.PointerType):
                            pointee: ir.Type = var_type.pointee
                            if isinstance(pointee, ir.ArrayType):
                                TargetType = pointee.element
                        elif isinstance(var_type, ir.ArrayType):
                            TargetType = var_type.element
                Value: ir.Value | None = self.HandleExprLlvm(Node.value, VarType=TargetType)
                if Value:
                    self._HandleSubscriptStoreLlvm(Target, Value)
            elif isinstance(Target, ast.Tuple):
                if isinstance(Node.value, ast.Call):
                    FuncName: str | None = None
                    ModulePath: str | None = None
                    if isinstance(Node.value.func, ast.Name):
                        FuncName = Node.value.func.id
                    elif isinstance(Node.value.func, ast.Attribute):
                        FuncName = Node.value.func.attr
                        ModulePath = self.Trans.ExprCallHandle._get_ModulePath(Node.value.func.value)
                    CReturnTypes: list[ast.expr] = []
                    FuncDef: ast.FunctionDef | None = self.Trans.FunctionDefCache.get(FuncName) if FuncName else None
                    if FuncDef:
                        if FuncDef.returns and isinstance(FuncDef.returns, ast.Subscript):
                            if isinstance(FuncDef.returns.value, ast.Name) and FuncDef.returns.value.id == 'tuple':
                                slice_node: ast.expr = FuncDef.returns.slice
                                if isinstance(slice_node, ast.Tuple):
                                    CReturnTypes = slice_node.elts
                                else:
                                    CReturnTypes = [slice_node]
                        if FuncDef.decorator_list:
                            for decorator in FuncDef.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 not CReturnTypes and FuncName:
                        func: ir.Function | None = Gen.functions.get(FuncName)
                        if func:
                            func_ft: ir.FunctionType | None = getattr(func, 'ftype', None)
                            if func_ft:
                                ret_type: ir.Type = func_ft.return_type
                                if isinstance(ret_type, ir.LiteralStructType):
                                    CReturnTypes = [None] * len(ret_type.elements)
                        if not CReturnTypes:
                            sym_key: str = FuncName
                            if not self.Trans.SymbolTable.has(sym_key):
                                if ModulePath:
                                    sym_key = f"{ModulePath}.{FuncName}"
                            sym_info: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(sym_key)
                            if sym_info and sym_info.IsFunction:
                                ret_type_info: CTypeInfo | None = sym_info.FuncPtrReturn
                                param_type_infos: list[tuple[str, CTypeInfo]] = [pt for _, pt in (sym_info.FuncPtrParams or [])]
                                if ret_type_info:
                                    if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
                                        ret_type: ir.Type = ret_type_info.ToLLVM(Gen)
                                    else:
                                        ret_type = Gen._type_str_to_llvm(str(ret_type_info) if ret_type_info else 'i32', False)
                                    if isinstance(ret_type, ir.LiteralStructType):
                                        CReturnTypes = [None] * len(ret_type.elements)
                                    if FuncName not in Gen.functions:
                                        if isinstance(ret_type, ir.VoidType):
                                            ret_type = ir.IntType(32)
                                        llvm_param_types: list[ir.Type] = []
                                        for pt in param_type_infos:
                                            if isinstance(pt, CTypeInfo) and pt.BaseType:
                                                lp: ir.Type = pt.ToLLVM(Gen)
                                            else:
                                                lp = Gen._type_str_to_llvm(str(pt) if pt else 'i32', '*' in str(pt) if isinstance(pt, str) else False)
                                            if isinstance(lp, ir.VoidType):
                                                lp = ir.IntType(8).as_pointer()
                                            llvm_param_types.append(lp)
                                        func_type: ir.FunctionType = ir.FunctionType(ret_type, llvm_param_types)
                                        MangledName: str = Gen._mangle_func_name(FuncName)
                                        func_decl: ir.Function = ir.Function(Gen.module, func_type, name=MangledName)
                                        Gen.functions[MangledName] = func_decl
                                        Gen.functions[FuncName] = func_decl
                    if not CReturnTypes and FuncName:
                        func: ir.Function | None = Gen.functions.get(FuncName)
                        if func:
                            func_ft: ir.FunctionType | None = getattr(func, 'ftype', None)
                            if func_ft:
                                ret_type: ir.Type = func_ft.return_type
                                if isinstance(ret_type, ir.LiteralStructType):
                                    CReturnTypes = [None] * len(ret_type.elements)
                    if CReturnTypes and len(Target.elts) == len(CReturnTypes):
                            CallArgs: list[ir.Value | None] = []
                            for arg in Node.value.args:
                                ArgVal: ir.Value | None = self.HandleExprLlvm(arg)
                                if ArgVal:
                                    CallArgs.append(ArgVal)
                            for kw in Node.value.keywords:
                                pass
                            func: ir.Function | None = Gen.functions.get(FuncName)
                            func_ft: ir.FunctionType | None = getattr(func, 'ftype', None) if func else None
                            func_params: list[ir.Type] = list(getattr(func_ft, 'args', []) or []) if func_ft else []
                            while len(CallArgs) < len(func_params):
                                FuncDef: ast.FunctionDef | None = self.Trans.FunctionDefCache.get(FuncName)
                                if FuncDef and len(CallArgs) < len(FuncDef.args.args):
                                    arg_def: list[ast.expr] = FuncDef.args.defaults
                                    arg_idx: int = len(CallArgs)
                                    total_args: int = len(FuncDef.args.args)
                                    default_start: int = total_args - len(arg_def)
                                    if arg_idx >= default_start:
                                        def_idx: int = arg_idx - default_start
                                        if def_idx < len(arg_def):
                                            DefVal: ir.Value | None = self.HandleExprLlvm(arg_def[def_idx])
                                            if DefVal:
                                                expected_type: ir.Type = func_params[arg_idx]
                                                if DefVal.type != expected_type:
                                                    if isinstance(expected_type, ir.IntType) and isinstance(DefVal.type, ir.IntType):
                                                        if DefVal.type.width < expected_type.width:
                                                            DefVal = Gen.builder.zext(DefVal, expected_type, name=f"zext_default_{arg_idx}")
                                                        elif DefVal.type.width > expected_type.width:
                                                            DefVal = Gen.builder.trunc(DefVal, expected_type, name=f"trunc_default_{arg_idx}")
                                                CallArgs.append(DefVal)
                                                continue
                                if len(CallArgs) < len(func_params):
                                    CallArgs.append(ir.Constant(func_params[len(CallArgs)], 0))
                                else:
                                    break
                            adjusted: list[ir.Value] = Gen._adjust_args(CallArgs, func)
                            call_result: ir.Value = Gen.builder.call(func, adjusted, name=f"call_{FuncName}")
                            func_ft: ir.FunctionType | None = getattr(func, 'ftype', None)
                            ret_type: ir.Type | None = getattr(func_ft, 'return_type', None) if func_ft else None
                            for j, elt in enumerate(Target.elts):
                                    if isinstance(elt, ast.Name):
                                        VarName: str = elt.id
                                        field_val: ir.Value = Gen.builder.extract_value(call_result, j, name=f"extract_{FuncName}_{j}")
                                        VarType: ir.Type
                                        if CReturnTypes[j] is not None:
                                            ReturnTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(CReturnTypes[j], self.Trans.SymbolTable)
                                            if ReturnTypeInfo is None:
                                                ReturnTypeInfo = CTypeInfo()
                                                ReturnTypeInfo.BaseType = t.CInt()
                                            VarType = Gen._ctype_to_llvm(ReturnTypeInfo)
                                        elif ret_type and isinstance(ret_type, ir.LiteralStructType) and j < len(ret_type.elements):
                                            VarType = ret_type.elements[j]
                                        else:
                                            VarType = field_val.type
                                        if isinstance(VarType, ir.VoidType):
                                            VarType = ir.IntType(32)
                                        var: ir.AllocaInstr = Gen._alloca(VarType, name=VarName)
                                        Gen.variables[VarName] = var
                                        if CReturnTypes[j] is not None:
                                            Gen._record_var_signedness(VarName, ReturnTypeStr)
                                        elif ret_type and isinstance(ret_type, ir.LiteralStructType) and j < len(ret_type.elements):
                                            elem_type: ir.Type = ret_type.elements[j]
                                            if isinstance(elem_type, ir.IntType):
                                                if elem_type.width == 16:
                                                    Gen._record_var_signedness(VarName, 'unsigned short')
                                                elif elem_type.width == 32:
                                                    Gen._record_var_signedness(VarName, 'unsigned int')
                                                elif elem_type.width == 64:
                                                    Gen._record_var_signedness(VarName, 'unsigned long long')
                                        Gen._store(field_val, var)
                    return

    def _InitStructAtPtr(self, call_node: ast.Call, ClassName: str, VarPtr: ir.Value) -> None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        if ClassName not in Gen.structs:
            return
        StructType: ir.Type = Gen.structs[ClassName]
        StructPtrType: ir.PointerType = ir.PointerType(StructType)
        RawPtr: ir.Value = Gen._load(VarPtr, name=getattr(VarPtr, 'name', 'ptr'))
        StructPtr: ir.Value = Gen.builder.bitcast(RawPtr, StructPtrType, name=ClassName)
        members: list[tuple[str, ir.Type]] = Gen.class_members.get(ClassName, [])
        defaults: dict[str, ir.Value] = Gen.class_member_defaults.get(ClassName, {})
        member_values: dict[str, ir.Value] = {}
        for member_name, member_type in members:
            if member_name in defaults:
                member_values[member_name] = defaults[member_name]
        if call_node.args:
            for i, arg in enumerate(call_node.args):
                if i < len(members):
                    member_name: str = members[i][0]
                    val: ir.Value | None = self.HandleExprLlvm(arg)
                    if val:
                        member_values[member_name] = val
        if call_node.keywords:
            for kw in call_node.keywords:
                val: ir.Value | None = self.HandleExprLlvm(kw.value)
                if val:
                    member_values[kw.arg] = val
        has_vtable: bool = ClassName in Gen.class_vtable or ClassName in Gen._cross_module_vtable_classes
        base: int = 1 if has_vtable else 0
        for i, (member_name, member_type) in enumerate(members):
            if isinstance(member_type, ir.VoidType):
                continue
            if member_name in member_values:
                ElemPtr: ir.Value = Gen.builder.gep(StructPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), base + i)], name=f"{ClassName}_{member_name}")
                try:
                    Gen._store(member_values[member_name], ElemPtr)
                except Exception as _e:
                    if _config_mode == "strict":
                        self.Trans.LogWarning(f"异常被忽略: {_e}")
        InitFuncName: str = f'{ClassName}.__init__'
        if Gen._has_function(InitFuncName):
            Args: list[ir.Value | None] = [self.HandleExprLlvm(arg) for arg in call_node.args]
            Args = [a for a in Args if a]
            Gen.builder.call(Gen._get_function(InitFuncName), [StructPtr] + Args, name=f"call_{InitFuncName}")

    def _HandleAttributeStoreLlvm(self, Target: ast.Attribute, Value: ir.Value) -> None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        AttrName: str = Target.attr
        if isinstance(Target.value, ast.Name) and Target.value.id == 'self':
            ClassName: str | None = self.Trans._CurrentCpythonObjectClass
            if ClassName and ClassName in Gen.structs:
                PropKey: str = f'{ClassName}.{AttrName}'
                PropInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(PropKey)
                if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_SETTER in PropInfo.MetaList:
                    SelfVar: ir.Value | None = Gen._get_var_ptr('self')
                    if SelfVar:
                        SelfPtr: ir.Value = Gen._load(SelfVar, name="self")
                        SetterFunc: ir.Function | None = Gen._get_function(PropKey + '$set')
                        if SetterFunc and SelfPtr:
                            Gen.builder.call(SetterFunc, [SelfPtr, Value], name=f"prop_set_{PropKey}")
                            return
                SelfVar: ir.Value | None = Gen._get_var_ptr('self')
                if not SelfVar:
                    return
                if SelfVar:
                    SelfPtr: ir.Value = Gen._load(SelfVar, name="self")
                    is_vtable_method: bool = False
                    method_idx: int = 0
                    if ClassName in Gen.class_vtable or ClassName in Gen._cross_module_vtable_classes:
                        if ClassName in Gen.class_methods:
                            for mi, mn in enumerate(Gen.class_methods[ClassName]):
                                method_short: str = mn.split('.')[-1] if '.' in mn else mn
                                if method_short == AttrName or mn == AttrName:
                                    is_vtable_method = True
                                    method_idx = mi
                                    break
                    if is_vtable_method:
                        VtableSlotPtr: ir.Value = Gen.builder.gep(SelfPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"vtable_slot_{ClassName}")
                        VtablePtr: ir.Value = Gen._load(VtableSlotPtr, name=f"vtable_ptr_{ClassName}")
                        methods: list[str] = Gen.class_methods[ClassName]
                        VtableArrayType: ir.ArrayType = ir.ArrayType(ir.PointerType(ir.IntType(8)), len(methods))
                        ClassVtable: ir.GlobalVariable | None = Gen.Vtables.get(ClassName)
                        if ClassVtable:
                            ClassVtableAddr: ir.Value = Gen.builder.bitcast(ClassVtable, ir.PointerType(ir.IntType(8)), name=f"class_vtable_addr_{ClassName}")
                            IsSameVtable: ir.Value = Gen.builder.icmp_unsigned('==', VtablePtr, ClassVtableAddr, name=f"is_same_vtable_{ClassName}")
                            CopyBlock: ir.Block = Gen.func.append_basic_block(name=f"vtable_copy_self_{AttrName}")
                            SkipBlock: ir.Block = Gen.func.append_basic_block(name=f"vtable_skip_self_{AttrName}")
                            Gen.builder.cbranch(IsSameVtable, CopyBlock, SkipBlock)
                            Gen.builder.position_at_end(CopyBlock)
                            Gen._vtable_copy_counter += 1
                            CopyName: str = f"{Gen._mangle_name(ClassName)}_vtable_copy_self_{Gen._vtable_copy_counter}"
                            VtableCopyGlobal: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VtableArrayType, name=CopyName)
                            VtableCopyGlobal.linkage = 'internal'
                            VtableCopyGlobal.initializer = ir.Constant(VtableArrayType, [ir.Constant(ir.PointerType(ir.IntType(8)), None)] * len(methods))
                            VtableCopyTyped: ir.Value = Gen.builder.bitcast(VtableCopyGlobal, ir.PointerType(ir.IntType(8)), name=f"vtable_copy_typed")
                            SrcTyped: ir.Value = Gen.builder.bitcast(ClassVtable, ir.PointerType(ir.IntType(8)), name=f"src_vtable_typed")
                            VtableSize: int = len(methods) * Gen.ptr_size
                            MemcpyFunc: ir.Function | None = Gen._find_function('llvm.memcpy.p0i8.p0i8.i64')
                            if not MemcpyFunc:
                                MemcpyType: ir.FunctionType = ir.FunctionType(ir.VoidType(), [ir.PointerType(ir.IntType(8)), ir.PointerType(ir.IntType(8)), ir.IntType(64), ir.IntType(1)])
                                MemcpyFunc = ir.Function(Gen.module, MemcpyType, name='llvm.memcpy.p0i8.p0i8.i64')
                                Gen.functions['llvm.memcpy.p0i8.p0i8.i64'] = MemcpyFunc
                            Gen.builder.call(MemcpyFunc, [VtableCopyTyped, SrcTyped, ir.Constant(ir.IntType(64), VtableSize), ir.Constant(ir.IntType(1), 0)])
                            VtableCopyGlobalAddr: ir.Value = Gen.builder.bitcast(VtableCopyGlobal, ir.PointerType(ir.IntType(8)), name=f"vtable_copy_addr")
                            Gen._store(VtableCopyGlobalAddr, VtableSlotPtr)
                            Gen.builder.branch(SkipBlock)
                            Gen.builder.position_at_end(SkipBlock)
                            VtablePtr = Gen._load(VtableSlotPtr, name=f"vtable_ptr_{ClassName}_after_copy")
                        VtableTyped: ir.Value = Gen.builder.bitcast(VtablePtr, ir.PointerType(VtableArrayType), name=f"vtable_typed_{ClassName}")
                        MethodPtrAddr: ir.Value = Gen.builder.gep(VtableTyped, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), method_idx)], name=f"vmethod_slot_{AttrName}")
                        FuncPtrI8: ir.Value = Gen.builder.bitcast(Value, ir.PointerType(ir.IntType(8)), name=f"func_ptr_i8_{AttrName}")
                        Gen._store(FuncPtrI8, MethodPtrAddr)
                        return
                    offset: int = Gen._get_member_offset(AttrName, ClassName)
                    struct_type: ir.Type = Gen.structs[ClassName]
                    max_offset: int = len(struct_type.elements) if isinstance(struct_type, ir.IdentifiedStructType) else 0
                    if offset >= max_offset:
                        VarName: str = f"self.{AttrName}"
                        if VarName not in Gen.variables:
                            NewVar: ir.AllocaInstr = Gen._allocaEntry(Value.type, name=AttrName)
                            Gen.variables[VarName] = NewVar
                        Gen._store(Value, Gen.variables[VarName])
                        return
                    MemberPtr: ir.Value = Gen.builder.gep(SelfPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                    self._StoreWithCoerce(Value, MemberPtr)
        elif isinstance(Target.value, ast.Name):
            VarName: str = Target.value.id

            # FakeDuck: 检查是否有影子结构体 a__meta__ (str 变量的 per-instance 字段存储)
            # 直接通过 a.__field__ = value 访问影子结构体字段 (语法糖)
            _fd_meta_name: str = f"{VarName}__meta__"
            if _fd_meta_name in Gen.variables and '_str' in Gen.structs:
                _fd_offset = Gen._get_member_offset(AttrName, '_str')
                if _fd_offset is not None:
                    _fd_meta_ptr: ir.Value = Gen.variables[_fd_meta_name]
                    _fd_field_ptr: ir.Value = Gen.builder.gep(_fd_meta_ptr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), _fd_offset)], name=f"{VarName}_{AttrName}_ptr")
                    self._StoreWithCoerce(Value, _fd_field_ptr)
                    return

            ClassName: str | None = Gen.var_struct_class.get(VarName)

            if not ClassName and Gen.global_struct_class:
                ClassName = Gen.global_struct_class.get(VarName)
                if ClassName:
                    Gen.var_struct_class[VarName] = ClassName

            if not ClassName:
                for CN in Gen.structs:
                    if VarName == CN.lower() or VarName.startswith(CN):
                        ClassName = CN
                        break

            if not ClassName and VarName in Gen.module.globals:
                GVar: ir.GlobalVariable = Gen.module.globals[VarName]
                if isinstance(GVar.type, ir.PointerType) and isinstance(GVar.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType)):
                    found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(GVar.type.pointee)
                    if found:
                        ClassName = found[0]
                        Gen.var_struct_class[VarName] = ClassName
                        if Gen.global_struct_class:
                            Gen.global_struct_class[VarName] = ClassName

            if not ClassName and VarName in Gen.variables:
                VarPtr: ir.Value = Gen.variables[VarName]
                if isinstance(VarPtr.type, ir.PointerType):
                    pointee: ir.Type = VarPtr.type.pointee
                    if isinstance(pointee, ir.PointerType):
                        pointee = pointee.pointee
                    found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(pointee)
                    if found:
                        CN: str = found[0]
                        ST: ir.Type = found[1]
                        ClassName = CN
                    elif isinstance(pointee, ir.IdentifiedStructType):
                        # sha1 冲突 fallback：find_struct_by_pointee 因 sha1 前缀不匹配失败时，
                        # 用短名（去掉 sha1 前缀）匹配，优先选字段最多的完整版本
                        pointee_short: str = Gen._extract_short_name(pointee.name)
                        best_elem_count: int = 0
                        for CN, ST in Gen.structs.items():
                            if isinstance(ST, ir.IdentifiedStructType):
                                st_short: str = Gen._extract_short_name(ST.name)
                                if st_short == pointee_short:
                                    elem_count: int = len(ST.elements) if ST.elements else 0
                                    if elem_count > best_elem_count:
                                        ClassName = CN
                                        best_elem_count = elem_count

            IsUnion: bool = False
            if ClassName:
                TypeInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(ClassName)
                if TypeInfo and TypeInfo.IsUnion:
                    IsUnion = True

            if ClassName and ClassName in Gen.structs:
                PropKey: str = f'{ClassName}.{AttrName}'
                PropInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(PropKey)
                if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_SETTER in PropInfo.MetaList:
                    ObjVal: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
                    SetterFunc: ir.Function | None = Gen._get_function(PropKey + '$set')
                    if SetterFunc and ObjVal:
                        if isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.PointerType):
                            ObjVal = Gen._load(ObjVal, name=f"Load_{ClassName}")
                        Gen.builder.call(SetterFunc, [ObjVal, Value], name=f"prop_set_{PropKey}")
                        return
                ObjVal: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
                if ObjVal:
                    if BaseHandle._is_char_pointer(ObjVal):
                        ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}")
                    if isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.PointerType):
                        ObjVal = Gen._load(ObjVal, name=f"Load_{ClassName}")
                    # 跨模块 opaque 类型：ObjVal.type.pointee 与 Gen.structs[ClassName] 可能是
                    # 不同的 IdentifiedStructType 对象（虽然 name 相同），== 返回 False。
                    # 使用 name 匹配作为 fallback，与链式赋值路径（第 926-927 行）一致。
                    # sha1 冲突时还需短名匹配（如 6bc91356c652f8ca.Function vs 8ad0c0a2934ca5b4.Function）
                    _ObjPointee = ObjVal.type.pointee if isinstance(ObjVal.type, ir.PointerType) else None
                    _TargetStruct = Gen.structs.get(ClassName)
                    _MatchesStruct = (_ObjPointee is not None and _TargetStruct is not None and
                                      (_ObjPointee == _TargetStruct or
                                       (isinstance(_ObjPointee, ir.IdentifiedStructType) and isinstance(_TargetStruct, ir.IdentifiedStructType) and
                                        (_ObjPointee.name == _TargetStruct.name or
                                         Gen._extract_short_name(_ObjPointee.name) == Gen._extract_short_name(_TargetStruct.name)))))
                    if isinstance(ObjVal.type, ir.PointerType) and _MatchesStruct:
                        if IsUnion:
                            NestedStructName: str = f"{ClassName}_{AttrName}"
                            if NestedStructName in Gen.structs:
                                NestedStructType: ir.Type = Gen.structs[NestedStructName]
                                ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(NestedStructType), name=f"cast_{NestedStructName}")
                                offset: int | None = Gen._get_member_offset(AttrName, NestedStructName)
                                if offset is not None and offset < len(NestedStructType.elements):
                                    MemberPtr: ir.Value = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                                    self._StoreWithCoerce(Value, MemberPtr)
                                return
                        bitfield_offsets: dict[str, int] = Gen.class_member_bitoffsets.get(ClassName, {})
                        if AttrName in bitfield_offsets:
                            self._store_bitfield_member(ObjVal, ClassName, AttrName, Value)
                            return
                        bitfields: dict[str, int] = Gen.class_member_bitfields.get(ClassName, {})
                        if AttrName in bitfields and bitfields[AttrName] > 0:
                            if ClassName not in Gen.class_member_bitoffsets:
                                Gen.class_member_bitoffsets[ClassName] = {}
                            if AttrName not in Gen.class_member_bitoffsets[ClassName]:
                                bo: int = 0
                                for bf_name, bf_width in bitfields.items():
                                    if bf_name == AttrName:
                                        break
                                    bo += bf_width
                                Gen.class_member_bitoffsets[ClassName][AttrName] = bo
                            self._store_bitfield_member(ObjVal, ClassName, AttrName, Value)
                            return
                        is_vtable_method: bool = False
                        method_idx: int = 0
                        if ClassName in Gen.class_vtable or ClassName in Gen._cross_module_vtable_classes:
                            if ClassName in Gen.class_methods:
                                for mi, mn in enumerate(Gen.class_methods[ClassName]):
                                    method_short: str = mn.split('.')[-1] if '.' in mn else mn
                                    if method_short == AttrName or mn == AttrName:
                                        is_vtable_method = True
                                        method_idx = mi
                                        break
                        if is_vtable_method:
                            VtableSlotPtr: ir.Value = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"vtable_slot_{ClassName}")
                            VtablePtr: ir.Value = Gen._load(VtableSlotPtr, name=f"vtable_ptr_{ClassName}")
                            methods: list[str] = Gen.class_methods[ClassName]
                            VtableArrayType: ir.ArrayType = ir.ArrayType(ir.PointerType(ir.IntType(8)), len(methods))
                            ClassVtable: ir.GlobalVariable | None = Gen.Vtables.get(ClassName)
                            if ClassVtable:
                                ClassVtableAddr: ir.Value = Gen.builder.bitcast(ClassVtable, ir.PointerType(ir.IntType(8)), name=f"class_vtable_addr_{ClassName}")
                                IsSameVtable: ir.Value = Gen.builder.icmp_unsigned('==', VtablePtr, ClassVtableAddr, name=f"is_same_vtable_{ClassName}")
                                CopyBlock: ir.Block = Gen.func.append_basic_block(name=f"vtable_copy_{AttrName}")
                                SkipBlock: ir.Block = Gen.func.append_basic_block(name=f"vtable_skip_{AttrName}")
                                Gen.builder.cbranch(IsSameVtable, CopyBlock, SkipBlock)
                                Gen.builder.position_at_end(CopyBlock)
                                Gen._vtable_copy_counter += 1
                                CopyName: str = f"{Gen._mangle_name(ClassName)}_vtable_copy_{Gen._vtable_copy_counter}"
                                VtableCopyGlobal: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VtableArrayType, name=CopyName)
                                VtableCopyGlobal.linkage = 'internal'
                                VtableCopyGlobal.initializer = ir.Constant(VtableArrayType, [ir.Constant(ir.PointerType(ir.IntType(8)), None)] * len(methods))
                                VtableCopyTyped: ir.Value = Gen.builder.bitcast(VtableCopyGlobal, ir.PointerType(ir.IntType(8)), name=f"vtable_copy_typed")
                                SrcTyped: ir.Value = Gen.builder.bitcast(ClassVtable, ir.PointerType(ir.IntType(8)), name=f"src_vtable_typed")
                                VtableSize: int = len(methods) * Gen.ptr_size
                                MemcpyFunc: ir.Function | None = Gen._find_function('llvm.memcpy.p0i8.p0i8.i64')
                                if not MemcpyFunc:
                                    MemcpyType: ir.FunctionType = ir.FunctionType(ir.VoidType(), [ir.PointerType(ir.IntType(8)), ir.PointerType(ir.IntType(8)), ir.IntType(64), ir.IntType(1)])
                                    MemcpyFunc = ir.Function(Gen.module, MemcpyType, name='llvm.memcpy.p0i8.p0i8.i64')
                                    Gen.functions['llvm.memcpy.p0i8.p0i8.i64'] = MemcpyFunc
                                Gen.builder.call(MemcpyFunc, [VtableCopyTyped, SrcTyped, ir.Constant(ir.IntType(64), VtableSize), ir.Constant(ir.IntType(1), 0)])
                                VtableCopyGlobalAddr: ir.Value = Gen.builder.bitcast(VtableCopyGlobal, ir.PointerType(ir.IntType(8)), name=f"vtable_copy_addr")
                                Gen._store(VtableCopyGlobalAddr, VtableSlotPtr)
                                Gen.builder.branch(SkipBlock)
                                Gen.builder.position_at_end(SkipBlock)
                                VtablePtr = Gen._load(VtableSlotPtr, name=f"vtable_ptr_{ClassName}_after_copy")
                            VtableTyped: ir.Value = Gen.builder.bitcast(VtablePtr, ir.PointerType(VtableArrayType), name=f"vtable_typed_{ClassName}")
                            MethodPtrAddr: ir.Value = Gen.builder.gep(VtableTyped, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), method_idx)], name=f"vmethod_slot_{AttrName}")
                            FuncPtrI8: ir.Value = Gen.builder.bitcast(Value, ir.PointerType(ir.IntType(8)), name=f"func_ptr_i8_{AttrName}")
                            Gen._store(FuncPtrI8, MethodPtrAddr)
                            return
                        offset: int | None = Gen._get_member_offset(AttrName, ClassName)
                        StructType: ir.Type | None = Gen.structs.get(ClassName)
                        if isinstance(StructType, ir.IdentifiedStructType) and (StructType.elements is None or len(StructType.elements) == 0):
                            self.Trans.ImportHandler._TryLoadStructFromStub(ClassName, Gen)
                            StructType = Gen.structs.get(ClassName)
                            if isinstance(StructType, ir.IdentifiedStructType) and (StructType.elements is None or len(StructType.elements) == 0):
                                return
                            # 重新计算 offset：_TryLoadStructFromStub 刚加载了 struct body，
                            # 之前 offset 可能因 struct opaque / class_members 不完整而返回 None
                            offset = Gen._get_member_offset(AttrName, ClassName)
                        # sha1 冲突修复：Gen.structs[ClassName] 可能是字段不全的版本（如 2 字段 Function
                        # 来自 MetaType.py scope，而正确版本是 8 字段 Function 来自 __function.py）。
                        # _get_member_offset 通过 class_sha1_map 已返回正确的 offset（如 5），
                        # 但 StructType 可能只有 2 个 elements，导致 offset < len(elements) 失败。
                        # 在所有 structs 中查找同短名且字段最多的版本。
                        if offset is not None and isinstance(StructType, ir.IdentifiedStructType) and StructType.elements is not None and offset >= len(StructType.elements):
                            _short: str = Gen._extract_short_name(StructType.name)
                            _best: int = len(StructType.elements)
                            for _cn, _st in Gen.structs.items():
                                if isinstance(_st, ir.IdentifiedStructType) and _st.elements is not None:
                                    if Gen._extract_short_name(_st.name) == _short and len(_st.elements) > _best:
                                        StructType = _st
                                        _best = len(_st.elements)
                        # bitcast：当 ObjVal 的 pointee 是 opaque 或与 StructType 不是同一个类型对象
                        # （sha1 前缀不同但短名相同）时，需要 bitcast 到 StructType 才能正确 GEP
                        if StructType is not None and StructType.elements is not None and isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.IdentifiedStructType) and (ObjVal.type.pointee.elements is None or ObjVal.type.pointee != StructType):
                            ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(StructType), name=f"cast_{ClassName}")
                        if offset is not None and StructType is not None and StructType.elements is not None and offset < len(StructType.elements):
                            MemberPtr: ir.Value = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                        else:
                            return

                        byte_order: str = Gen.class_member_byteorders.get(ClassName, {}).get(AttrName, "")

                        if byte_order == 'big':
                            if StructType is None or StructType.elements is None or len(StructType.elements) == 0:
                                return
                            member_type: ir.Type = StructType.elements[offset]
                            if isinstance(member_type, ir.IntType):
                                Value = Gen._apply_bswap_if_big(Value, byte_order, f"bswap_store_{AttrName}")

                        self._StoreWithCoerce(Value, MemberPtr)
            if not ClassName:
                imported_modules: list[str] | None = getattr(self.Trans, '_ImportedModules', None)
                resolved_mod: str = self.Trans.SymbolTable.resolve_alias(VarName)
                if imported_modules and (VarName in imported_modules or resolved_mod in imported_modules):
                    PossibleKeys: list[str] = [f"{VarName}.{AttrName}", AttrName]
                    for mod_name in imported_modules:
                        if mod_name.endswith(f".{VarName}") or mod_name == VarName:
                            key: str = f"{mod_name}.{AttrName}"
                            if key not in PossibleKeys:
                                PossibleKeys.append(key)
                    for key in PossibleKeys:
                        if key in Gen.module.globals:
                            GVar: ir.GlobalVariable = Gen.module.globals[key]
                            if isinstance(GVar, ir.Function):
                                return
                            if isinstance(GVar.type, ir.PointerType) and isinstance(GVar.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)):
                                return
                            self._StoreWithCoerce(Value, GVar)
                            return
                    ModuleSha1Map: dict[str, str] = Gen.ModuleSha1Map
                    sha1_candidates: list[str] = [VarName, resolved_mod]
                    for mod_name in imported_modules:
                        if mod_name.endswith(f".{VarName}") or mod_name == VarName:
                            if mod_name not in sha1_candidates:
                                sha1_candidates.append(mod_name)
                    for cand in sha1_candidates:
                        sha1: str | None = ModuleSha1Map.get(cand)
                        if sha1:
                            prefixed: str = f"{sha1}.{AttrName}"
                            if prefixed in Gen.module.globals:
                                GVar2: ir.GlobalVariable = Gen.module.globals[prefixed]
                                if isinstance(GVar2, ir.Function):
                                    return
                                if isinstance(GVar2.type, ir.PointerType) and isinstance(GVar2.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)):
                                    return
                                self._StoreWithCoerce(Value, GVar2)
                                return
        elif isinstance(Target.value, ast.Attribute):
            ObjVal: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
            if ObjVal and isinstance(ObjVal.type, ir.PointerType):
                pointee: ir.Type = ObjVal.type.pointee
                if isinstance(pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                    if isinstance(pointee, ir.IdentifiedStructType) and pointee.elements is None:
                        for CN, ST in Gen.structs.items():
                            if isinstance(ST, ir.IdentifiedStructType) and ST.name == pointee.name and ST.elements is not None:
                                pointee = ST
                                ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(ST), name=f"cast_{CN}")
                                break
                    found_match: bool = False
                    for CN, ST in Gen.structs.items():
                        if pointee == ST or (isinstance(pointee, ir.IdentifiedStructType) and isinstance(ST, ir.IdentifiedStructType) and pointee.name == ST.name):
                            found_match = True
                            if ST.elements is None:
                                self.Trans.ImportHandler._TryLoadStructFromStub(CN, Gen)
                                ST = Gen.structs.get(CN, ST)
                            if ST.elements is not None and isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.IdentifiedStructType) and ObjVal.type.pointee.elements is None:
                                ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(ST), name=f"cast_{CN}")
                            bitfield_offsets: dict[str, int] = Gen.class_member_bitoffsets.get(CN, {})
                            if AttrName in bitfield_offsets:
                                self._store_bitfield_member(ObjVal, CN, AttrName, Value)
                                return
                            offset: int = Gen._get_member_offset(AttrName, CN)
                            if offset is not None and ST.elements is not None and offset < len(ST.elements):
                                MemberPtr: ir.Value = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                                self._StoreWithCoerce(Value, MemberPtr)
                            break
                    if not found_match:
                        if isinstance(pointee, ir.IdentifiedStructType):
                            matched_cn: str | None = None
                            for CN in Gen.class_members:
                                members: list[tuple[str, ir.Type]] = Gen.class_members[CN]
                                for mname, mtype in members:
                                    if mname == AttrName:
                                        matched_cn = CN
                                        break
                                if matched_cn:
                                    break
                            if matched_cn and matched_cn in Gen.structs:
                                ST: ir.Type = Gen.structs[matched_cn]
                                if isinstance(ST, ir.IdentifiedStructType) and (ST.elements is None or len(ST.elements) == 0):
                                    self.Trans.ImportHandler._TryLoadStructFromStub(matched_cn, Gen)
                                    ST = Gen.structs.get(matched_cn, ST)
                                if ST.elements is not None and isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.IdentifiedStructType) and ObjVal.type.pointee.elements is None:
                                    ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(ST), name=f"cast_{matched_cn}")
                                offset: int = Gen._get_member_offset(AttrName, matched_cn)
                                if offset is not None and ST.elements is not None and offset < len(ST.elements):
                                    MemberPtr: ir.Value = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                                    self._StoreWithCoerce(Value, MemberPtr)
                                return
        elif isinstance(Target.value, ast.Call):
            # Check if this is c.Deref(...) — we need the pointer, not the Loaded value
            ObjVal: ir.Value | None = None
            is_cderef: bool = (isinstance(Target.value.func, ast.Attribute) and
                         isinstance(Target.value.func.value, ast.Name) and
                         Target.value.func.value.id == 'c' and
                         Target.value.func.attr == 'Deref' and
                         Target.value.args)
            if is_cderef:
                # Get the pointer from c.Deref argument, don't Load the value
                deref_arg: ast.expr = Target.value.args[0]
                inner_val: ir.Value | None = self.HandleExprLlvm(deref_arg)
                if inner_val and isinstance(inner_val.type, ir.PointerType):
                    if isinstance(inner_val.type.pointee, ir.PointerType):
                        ObjVal = Gen._load(inner_val, name="deref_load_ptr")
                    else:
                        ObjVal = inner_val
            if ObjVal is None:
                ObjVal = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
            if ObjVal and isinstance(ObjVal.type, ir.PointerType):
                pointee: ir.Type = ObjVal.type.pointee
                if isinstance(pointee, ir.PointerType):
                    ObjVal = Gen._load(ObjVal, name="load_ptr_for_attr")
                    pointee = ObjVal.type.pointee
                for CN, ST in Gen.structs.items():
                    if pointee == ST or (isinstance(pointee, ir.IdentifiedStructType) and isinstance(ST, ir.IdentifiedStructType) and pointee.name == ST.name):
                        if isinstance(ST, ir.IdentifiedStructType) and (ST.elements is None or len(ST.elements) == 0):
                            self.Trans.ImportHandler._TryLoadStructFromStub(CN, Gen)
                            ST = Gen.structs.get(CN, ST)
                        if ST.elements is not None and isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.IdentifiedStructType) and ObjVal.type.pointee.elements is None:
                            ObjVal = Gen.builder.bitcast(ObjVal, ir.PointerType(ST), name=f"cast_{CN}")
                        bitfield_offsets: dict[str, int] = Gen.class_member_bitoffsets.get(CN, {})
                        if AttrName in bitfield_offsets:
                            self._store_bitfield_member(ObjVal, CN, AttrName, Value)
                            return
                        offset: int = Gen._get_member_offset(AttrName, CN)
                        if offset is not None and ST.elements is not None and offset < len(ST.elements):
                            MemberPtr: ir.Value = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                            self._StoreWithCoerce(Value, MemberPtr)
                        break
        elif isinstance(Target.value, ast.Subscript):
            SubPtr: ir.Value | None = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Target.value)
            if SubPtr and isinstance(SubPtr.type, ir.PointerType):
                pointee: ir.Type = SubPtr.type.pointee

                if isinstance(Target.value.value, ast.Attribute):
                    AttrNameSub: str = Target.value.value.attr
                    if AttrNameSub == 'items' and 'Item' in Gen.structs:
                        ObjValCast: ir.Value = Gen.builder.bitcast(SubPtr, ir.PointerType(Gen.structs['Item']), name=f"cast_Item")
                        offset: int = Gen._get_member_offset(AttrName, 'Item')
                        MemberPtr: ir.Value = Gen.builder.gep(ObjValCast, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                        self._StoreWithCoerce(Value, MemberPtr)
                        return

                if BaseHandle._is_char_pointer(SubPtr):
                    for CN, ST in Gen.structs.items():
                        ObjValCast: ir.Value = Gen.builder.bitcast(SubPtr, ir.PointerType(ST), name=f"cast_{CN}")
                        offset: int = Gen._get_member_offset(AttrName, CN)
                        MemberPtr: ir.Value = Gen.builder.gep(ObjValCast, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                        self._StoreWithCoerce(Value, MemberPtr)
                        break
                elif isinstance(pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
                    found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(pointee)
                    if found:
                        CN: str = found[0]
                        ST: ir.Type = found[1]
                        if isinstance(ST, ir.IdentifiedStructType) and (ST.elements is None or len(ST.elements) == 0):
                            self.Trans.ImportHandler._TryLoadStructFromStub(CN, Gen)
                            ST = Gen.structs.get(CN, ST)
                            if ST.elements is not None and isinstance(SubPtr.type, ir.PointerType) and isinstance(SubPtr.type.pointee, ir.IdentifiedStructType) and SubPtr.type.pointee.elements is None:
                                SubPtr = Gen.builder.bitcast(SubPtr, ir.PointerType(ST), name=f"cast_{CN}")
                        offset: int = Gen._get_member_offset(AttrName, CN)
                        if offset is not None and ST.elements is not None and offset < len(ST.elements):
                            MemberPtr: ir.Value = Gen.builder.gep(SubPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                            self._StoreWithCoerce(Value, MemberPtr)
                elif isinstance(pointee, ir.PointerType):
                    LoadedPtr: ir.Value = Gen._load(SubPtr, name=f"Load_{AttrName}_ptr")
                    if isinstance(LoadedPtr.type, ir.PointerType) and isinstance(LoadedPtr.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType)):
                        found: tuple[str, ir.Type] | None = Gen.find_struct_by_pointee(LoadedPtr.type.pointee)
                        if found:
                            CN: str = found[0]
                            ST: ir.Type = found[1]
                            offset: int = Gen._get_member_offset(AttrName, CN)
                            MemberPtr: ir.Value = Gen.builder.gep(LoadedPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=AttrName)
                            self._StoreWithCoerce(Value, MemberPtr)

    def _StoreArrElemWithCoerceBswap(self, Value: ir.Value, Ptr: ir.Value, arr_byte_order: str) -> None:
        """对数组元素存储应用 bswap 后再 coerce 存储"""
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        Value = Gen._apply_bswap_if_big(Value, arr_byte_order, "bswap_arr_store")
        self._StoreWithCoerce(Value, Ptr)

    def _HandleSubscriptStoreLlvm(self, Target: ast.Subscript, Value: ir.Value) -> None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        # 查询数组元素字节序
        arr_byte_order: str = ''
        if isinstance(Target.value, ast.Name) and Target.value.id in Gen.local_var_byteorders:
            arr_byte_order = Gen.local_var_byteorders[Target.value.id]
        if isinstance(Target.value, ast.Name):
            SubVarName: str = Target.value.id
            if SubVarName in Gen.var_const_flags:
                src_info: str = Gen._get_node_info()
                self.Trans.LogError(f"不能对 const 变量 '{SubVarName}' 的元素赋值{src_info}")
        ClassName: str | None = self.Trans.ExprHandler._get_var_class(Target.value, Gen)
        if ClassName and Gen._has_function(f'{ClassName}.__setitem__'):
            obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
            idx_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.slice)
            if obj_val and idx_val:
                # 处理 obj_val 为 i8（整数）的情况：联合类型 | t.CPtr 降级后可能被 load 为 i8
                if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8:
                    obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}")
                if BaseHandle._is_char_pointer(obj_val):
                    obj_val = Gen.builder.bitcast(obj_val, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}")
                setitem_args: list[ir.Value] = [obj_val, idx_val, Value]
                setitem_func_name: str = f'{ClassName}.__setitem__'
                setitem_args = Gen._apply_auto_addr(setitem_func_name, setitem_args)
                setitem_func: ir.Function = Gen._get_function(setitem_func_name)
                setitem_args = Gen._adjust_args(setitem_args, setitem_func)
                Gen.builder.call(setitem_func, setitem_args, name=f"call_{setitem_func_name}")
                return
        ValueVal: ir.Value | None = self.HandleExprLlvm(Target.value)
        IndexVal: ir.Value | None = self.HandleExprLlvm(Target.slice)
        if not ValueVal or not IndexVal:
            return
        # 当变量本身是二级指针（如 elem_ptr: T | t.CPtr = AST**），
        # 且存储的值也是指针时，elem_ptr[i] = item 应直接存储指针（8 字节），
        # 而非解引用后复制结构体（如 48 字节的 AST），避免对象切片
        if isinstance(Target.value, ast.Name):
            VarName: str = Target.value.id
            if VarName in Gen.variables and Gen.variables[VarName] is not None:
                VarAlloca: ir.Value = Gen.variables[VarName]
                if isinstance(VarAlloca.type, ir.PointerType) and isinstance(VarAlloca.type.pointee, ir.PointerType):
                    if (isinstance(ValueVal.type, ir.PointerType) and isinstance(Value.type, ir.PointerType)
                            and isinstance(Value.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType))):
                        if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64:
                            IndexVal = Gen.builder.zext(IndexVal, ir.IntType(64), name="zext_ptr_index_store")
                        # ValueVal 是 AST*（加载自 elem_ptr 的基指针），
                        # 但 GEP 默认将其视为 AST 结构体数组。需要先 bitcast 为
                        # AST**（指向 AST* 的指针），让 GEP 正确索引 AST* 指针数组，
                        # 而非 AST 结构体数组。然后用 builder.store 直接存储指针，
                        # 避免 _store 的类型强制转换将指针解引用为结构体。
                        PtrToStruct: ir.Type = Value.type.pointee
                        BaseAsPP: ir.Value = Gen.builder.bitcast(ValueVal,
                            ir.PointerType(ir.PointerType(PtrToStruct)), name="cast_base_pp")
                        ElemPtr: ir.Value = Gen.builder.gep(BaseAsPP, [IndexVal], name="subscript")
                        Gen.builder.store(Value, ElemPtr)
                        return
        if BaseHandle._is_char_pointer(IndexVal):
            Loaded_byte: ir.Value = Gen._load(IndexVal, name="Load_char_idx_store")
            IndexVal = Gen.builder.zext(Loaded_byte, ir.IntType(32), name="char_to_int_idx_store")
        if isinstance(ValueVal.type, ir.IntType):
            var_ptr: ir.Value | None = self._get_int_ptr(Target.value)
            if var_ptr:
                i8_ptr: ir.Value = Gen.builder.bitcast(var_ptr, ir.PointerType(ir.IntType(8)), name="int_to_i8ptr_store")
                if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64:
                    IndexVal = Gen.builder.zext(IndexVal, ir.IntType(64), name="zext_int_index_store")
                ptr: ir.Value = Gen.builder.gep(i8_ptr, [IndexVal], name="int_subscript_ptr_store")
                self._StoreWithCoerce(Value, ptr)
                return
        if isinstance(ValueVal.type, ir.PointerType) and isinstance(ValueVal.type.pointee, ir.PointerType):
            if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64:
                IndexVal = Gen.builder.zext(IndexVal, ir.IntType(64), name="zext_ptr_index_store")
            ElemPtr: ir.Value = Gen.builder.gep(ValueVal, [IndexVal], name="subscript")
            self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
            return
        if isinstance(ValueVal.type, ir.PointerType):
            pointee: ir.Type = ValueVal.type.pointee
            if isinstance(pointee, ir.ArrayType):
                zero: ir.Constant = ir.Constant(ir.IntType(32), 0)
                if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width != 32:
                    if IndexVal.type.width < 32:
                        IndexVal = Gen.builder.zext(IndexVal, ir.IntType(32), name="zext_arr_index")
                    else:
                        IndexVal = Gen.builder.trunc(IndexVal, ir.IntType(32), name="trunc_arr_index")
                ElemPtr: ir.Value = Gen.builder.gep(ValueVal, [zero, IndexVal], name="subscript")
            elif (isinstance(pointee, ir.IntType) and pointee.width == 8
                  and isinstance(Target.value, ast.Name)
                  and (Gen.var_ptr_element.get(Target.value.id, False)
                       or Gen.global_var_ptr_element.get(Target.value.id, False))):
                # 指针到 str/bytes 的变量 (BinOp 注解如 str | t.CPtr)
                # elem_ptr 是 i8* 但实际指向 i8* (字符串指针), elem_ptr[0] = item 应存储 8 字节
                CastedPtrPtr: ir.Value = Gen.builder.bitcast(ValueVal, ir.PointerType(ir.PointerType(ir.IntType(8))), name="cast_pp_str_store")
                if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64:
                    IndexVal = Gen.builder.zext(IndexVal, ir.IntType(64), name="zext_pp_str_index_store")
                ElemPtr = Gen.builder.gep(CastedPtrPtr, [IndexVal], name="subscript")
                self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
                return
            else:
                ElemPtr: ir.Value = Gen.builder.gep(ValueVal, [IndexVal], name="subscript")
            self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
        elif isinstance(ValueVal.type, ir.ArrayType):
            zero: ir.Constant = ir.Constant(ir.IntType(32), 0)
            if isinstance(Target.value, ast.Name):
                VarName: str = Target.value.id
                if VarName in Gen.variables and Gen.variables[VarName] is not None:
                    VarPtr: ir.Value = Gen.variables[VarName]
                    if isinstance(VarPtr.type, ir.PointerType) and isinstance(VarPtr.type.pointee, ir.ArrayType):
                        if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width != 32:
                            if IndexVal.type.width < 32:
                                IndexVal = Gen.builder.zext(IndexVal, ir.IntType(32), name="zext_arr_index")
                            else:
                                IndexVal = Gen.builder.trunc(IndexVal, ir.IntType(32), name="trunc_arr_index")
                        ElemPtr: ir.Value = Gen.builder.gep(VarPtr, [zero, IndexVal], name="subscript")
                        self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
                        return
            if isinstance(Target.value, ast.Subscript):
                InnerPtr: ir.Value | None = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Target.value)
                if InnerPtr:
                    if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width != 32:
                        if IndexVal.type.width < 32:
                            IndexVal = Gen.builder.zext(IndexVal, ir.IntType(32), name="zext_arr_index")
                        else:
                            IndexVal = Gen.builder.trunc(IndexVal, ir.IntType(32), name="trunc_arr_index")
                    ElemPtr: ir.Value = Gen.builder.gep(InnerPtr, [zero, IndexVal], name="subscript")
                    self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
                    return
            if isinstance(Target.value, ast.Attribute):
                AttrPtr: ir.Value | None = self.Trans.ExprAttrHandle._get_attr_ptr(Target.value)
                if AttrPtr and isinstance(AttrPtr.type, ir.PointerType) and isinstance(AttrPtr.type.pointee, ir.ArrayType):
                    if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width != 32:
                        if IndexVal.type.width < 32:
                            IndexVal = Gen.builder.zext(IndexVal, ir.IntType(32), name="zext_arr_index")
                        else:
                            IndexVal = Gen.builder.trunc(IndexVal, ir.IntType(32), name="trunc_arr_index")
                    ElemPtr: ir.Value = Gen.builder.gep(AttrPtr, [zero, IndexVal], name="subscript")
                    self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
                    return
            arr_alloc: ir.AllocaInstr = Gen._allocaEntry(ValueVal.type, name="arr_subscript_tmp")
            Gen._store(ValueVal, arr_alloc)
            ElemPtr: ir.Value = Gen.builder.gep(arr_alloc, [zero, IndexVal], name="subscript")
            self._StoreArrElemWithCoerceBswap(Value, ElemPtr, arr_byte_order)
            ModifiedArr: ir.Value = Gen._load(arr_alloc, name="modified_arr")
            if isinstance(Target.value, ast.Subscript):
                OuterPtr: ir.Value | None = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Target.value)
                if OuterPtr:
                    Gen._store(ModifiedArr, OuterPtr)
            elif isinstance(Target.value, ast.Attribute):
                OuterPtr: ir.Value | None = self.Trans.ExprAttrHandle._get_attr_ptr(Target.value)
                if OuterPtr:
                    Gen._store(ModifiedArr, OuterPtr)

    def _StoreWithCoerce(self, Value: ir.Value, Ptr: ir.Value) -> None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        if isinstance(Ptr.type, ir.PointerType):
            TargetType: ir.Type = Ptr.type.pointee
            if Value.type != TargetType:
                if isinstance(TargetType, ir.ArrayType) and isinstance(Value.type, ir.PointerType):
                    ElemType: ir.Type = TargetType.element
                    ElemSize: int = Gen._get_struct_size(ElemType)
                    for i in range(TargetType.count):
                        DstElem: ir.Value = Gen.builder.gep(Ptr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), i)], name=f"arr_dst_{i}")
                        SrcPtr: ir.Value
                        if ElemSize == 1:
                            SrcPtr = Gen.builder.gep(Value, [ir.Constant(ir.IntType(32), i)], name=f"arr_src_{i}")
                        else:
                            PtrInt: ir.Value = Gen.builder.ptrtoint(Value, ir.IntType(64))
                            Offset: ir.Constant = ir.Constant(ir.IntType(64), i * ElemSize)
                            NewPtrInt: ir.Value = Gen.builder.add(PtrInt, Offset)
                            SrcPtr = Gen.builder.inttoptr(NewPtrInt, ir.PointerType(ElemType), name=f"arr_src_{i}")
                        SrcVal: ir.Value = Gen._load(SrcPtr, name=f"arr_elem_{i}")
                        if SrcVal.type != ElemType:
                            try:
                                SrcVal = Gen.builder.bitcast(SrcVal, ElemType, name=f"arr_cast_{i}")
                            except Exception:  # 回退：bitcast 失败时跳过该元素
                                continue
                        Gen._store(SrcVal, DstElem)
                    return
                if isinstance(TargetType, ir.PointerType) and isinstance(Value, ir.Constant) and Value.constant is None:
                    Value = ir.Constant(TargetType, None)
                elif isinstance(TargetType, ir.PointerType) and isinstance(Value.type, ir.PointerType):
                    try:
                        Value = Gen.builder.bitcast(Value, TargetType, name="null_ptr_bitcast")
                    except Exception:  # 回退：bitcast 失败时设为 null 常量
                        Value = ir.Constant(TargetType, None)
                else:
                    Coerced: ir.Value | None = Gen._coerce_value(Value, TargetType)
                    if Coerced is not None:
                        Value = Coerced
        Gen._store(Value, Ptr)


    def _get_int_ptr(self, target: ast.expr) -> ir.Value | None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        if isinstance(target, ast.Name):
            VarName: str = target.id
            if VarName in Gen.variables and Gen.variables[VarName] is not None:
                VarPtr: ir.Value = Gen.variables[VarName]
                if isinstance(VarPtr.type, ir.PointerType):
                    pointee: ir.Type = VarPtr.type.pointee
                    if isinstance(pointee, ir.ArrayType):
                        return Gen.builder.gep(VarPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"arr_start_{VarName}")
        return None

    def _EmitGlobalAnnAssignLlvm(self, Node: ast.AnnAssign, Gen: "Translator.LlvmGen") -> None:
        if isinstance(Node.target, ast.Name):
            VarName: str = Node.target.id
            Info: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(VarName)
            if Info:
                if Info.IsTypedef:
                    return
            parse_result = ParseListAnnotation(Node.annotation)
            if parse_result:
                elem_type_node: ast.expr = parse_result.elem_type_node
                ElemType, ElemTypeInfo = self.ResolveListElementType(
                    elem_type_node, Gen,
                    check_func_ptr=True, void_fallback_width=32, fallback_to_cint=True,
                )
                if parse_result.is_pointer:
                    # 单参数 list[type] → 指针
                    VarType: ir.Type = ir.PointerType(ElemType)
                    if VarName not in Gen.variables and VarName not in Gen.module.globals:
                        GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VarType, name=VarName)
                        GlobalVar.initializer = ir.Constant(VarType, None)
                        Gen.variables[VarName] = GlobalVar
                        if isinstance(elem_type_node, ast.Name) and elem_type_node.id in Gen.structs:
                            Gen.global_struct_class[VarName] = elem_type_node.id
                    return
                count_node: ast.expr | None = parse_result.count_node
                ArrayCount: int = self.ParseArrayCount(count_node, Gen, Node.value, mode='global')
                VarType = ir.ArrayType(ElemType, ArrayCount)
                if VarName not in Gen.variables and VarName not in Gen.module.globals:
                    GlobalVar = ir.GlobalVariable(Gen.module, VarType, name=VarName)
                    if isinstance(ElemType, ir.IdentifiedStructType):
                        GlobalVar.linkage = 'common'
                    elif Node.value and isinstance(Node.value, ast.Constant) and isinstance(Node.value.value, str):
                        str_val: str = Node.value.value + '\x00'
                        str_bytes: bytearray = bytearray(str_val, 'utf-8')
                        if len(str_bytes) < ArrayCount:
                            str_bytes.extend(b'\x00' * (ArrayCount - len(str_bytes)))
                        try:
                            GlobalVar.initializer = ir.Constant(VarType, str_bytes[:ArrayCount])
                        except Exception:  # 回退：初始化常量失败时用零值
                            GlobalVar.initializer = Gen._zero_value_for_type(VarType)
                    else:
                        InitConstants: list[ir.Constant] | None = self.Trans._BuildArrayInitConstants(Node.value, ElemType, elem_type_node, ArrayCount, Gen, byte_order=ElemTypeInfo.ByteOrder if ElemTypeInfo else '')
                        if InitConstants:
                            GlobalVar.initializer = ir.Constant(VarType, InitConstants)
                        elif ArrayCount > 256:
                            GlobalVar.linkage = 'common'
                        else:
                            if self._contains_identified_struct(VarType):
                                GlobalVar.linkage = 'common'
                            else:
                                GlobalVar.initializer = ir.Constant(VarType, [ir.Constant(ElemType, ir.Undefined)] * ArrayCount)
                    Gen.variables[VarName] = GlobalVar
                    if isinstance(elem_type_node, ast.Name) and elem_type_node.id in Gen.structs:
                        Gen.global_struct_class[VarName] = elem_type_node.id
                return
            if isinstance(Node.annotation, ast.Name) and Node.annotation.id in Gen.structs:
                StructName: str = Node.annotation.id
                VarType: ir.Type = Gen.structs[StructName]
                if VarName not in Gen.variables and VarName not in Gen.module.globals:
                    GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VarType, name=VarName)
                    if Node.value and isinstance(Node.value, ast.Call) and isinstance(Node.value.func, ast.Name) and Node.value.func.id == StructName:
                        const: ir.Constant | None = self.Trans.ClassHandler._BuildStructConstant(Node.value, StructName, Gen)
                        if const:
                            GlobalVar.initializer = const
                        else:
                            GlobalVar.initializer = ir.Constant(VarType, None)
                    else:
                        GlobalVar.initializer = ir.Constant(VarType, None)
                    Gen.variables[VarName] = GlobalVar
                    Gen.global_struct_class[VarName] = StructName
                return
            TypeInfo: CTypeInfo | None = CTypeInfo.FromNode(Node.annotation, self.Trans.SymbolTable)
            IsCDefine: bool = False
            if TypeInfo and TypeInfo.BaseType:
                if isinstance(TypeInfo.BaseType, t._CTypedef):
                    return
                if isinstance(TypeInfo.BaseType, t.CDefine):
                    IsCDefine = True
            if not IsCDefine and self._IsTypedefAnnotation(Node.annotation):
                IsCDefine = True
                TTypeInfo: CTypeInfo | None = self.Trans.TypeMergeHandler.GetCTypeInfo(Node.annotation)
                if TTypeInfo:
                    TTypeInfo.IsTypedef = True
                    TTypeInfo.Name = VarName
                    self.Trans.SymbolTable.insert(VarName, TTypeInfo)
            if IsCDefine:
                if Node.value:
                    define_constants: dict[str, int | float] = vars(Gen).setdefault('_define_constants', {})
                    try:
                        const_value: int | float | None = self._eval_const_expr(Node.value, Gen)
                        if const_value is not None:
                            define_constants[VarName] = const_value
                    except Exception as _e:
                        if _config_mode == "strict":
                            self.Trans.LogWarning(f"异常被忽略: {_e}")
                return
            if TypeInfo is None:
                TypeInfo = CTypeInfo()
                TypeInfo.BaseType = t.CInt()
            VarType: ir.Type = Gen._ctype_to_llvm(TypeInfo)
            if isinstance(VarType, ir.VoidType):
                VarType = ir.IntType(32)
            if VarName in Gen.variables or VarName in Gen.module.globals:
                # 时序修复：第一遍创建全局时类未处理（SymbolTable 无枚举成员），
                # initializer 回退为 0。第二遍类已处理，尝试用解析出的枚举值更新 initializer。
                if VarName in Gen.module.globals and Node.value:
                    existing: Any = Gen.module.globals[VarName]
                    if isinstance(existing, ir.GlobalVariable) and isinstance(VarType, ir.IntType):
                        new_init: ir.Constant | None = self._eval_global_const(Node.value, VarType, Gen)
                        if new_init is not None:
                            existing.initializer = new_init
                return
            if isinstance(VarType, (ir.IdentifiedStructType, ir.LiteralStructType)):
                GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VarType, name=VarName)
                GlobalVar.initializer = ir.Constant(VarType, None)
                Gen.variables[VarName] = GlobalVar
                if TypeInfo and TypeInfo.IsStruct and TypeInfo.Name:
                    Gen.global_struct_class[VarName] = TypeInfo.Name
                return
            GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VarType, name=VarName)
            # 全局变量指针元素标志：bytes|t.CPtr 或 str|t.CPtr 注解的变量，
            # 使 var[index] 使用 8 字节指针步长（而非 1 字节字符步长）
            if isinstance(Node.annotation, ast.BinOp) and isinstance(Node.annotation.op, ast.BitOr):
                if AnnotationContainsName(Node.annotation, 'str') or AnnotationContainsName(Node.annotation, 'bytes'):
                    Gen.global_var_ptr_element[VarName] = True
            if Node.value:
                if isinstance(Node.value, ast.Constant) and isinstance(Node.value.value, str) and isinstance(VarType, ir.PointerType):
                    str_val: str = Node.value.value + '\x00'
                    str_bytes: bytes = str_val.encode('utf-8')
                    arr_type: ir.ArrayType = ir.ArrayType(ir.IntType(8), len(str_bytes))
                    str_gv_name: str = VarName + '_str'
                    str_gv: ir.GlobalVariable
                    if str_gv_name not in Gen.module.globals:
                        str_gv = ir.GlobalVariable(Gen.module, arr_type, name=str_gv_name)
                        str_gv.initializer = ir.Constant(arr_type, bytearray(str_bytes))
                        str_gv.linkage = 'internal'
                    else:
                        str_gv = Gen.module.globals[str_gv_name]
                    ptr_type: ir.PointerType = ir.PointerType(ir.IntType(8))
                    ptr_gv: ir.GlobalVariable
                    if VarName not in Gen.module.globals:
                        ptr_gv = ir.GlobalVariable(Gen.module, ptr_type, name=VarName)
                        ptr_gv.initializer = ir.Constant(ptr_type, str_gv)
                        ptr_gv.linkage = 'internal'
                    else:
                        ptr_gv = Gen.module.globals[VarName]
                    Gen.variables[VarName] = ptr_gv
                elif isinstance(VarType, ir.PointerType) and isinstance(VarType.pointee, ir.FunctionType) and isinstance(Node.value, ast.Name):
                    # 函数指针赋值：f3: t.Callable[[int], int] = f
                    RefName: str = Node.value.id
                    SymInfo: Any = self.Trans.SymbolTable.lookup(RefName)
                    if SymInfo and (SymInfo.IsFunction or SymInfo.IsFuncPtr):
                        MangledName: str = Gen._mangle_func_name(RefName)
                        if MangledName in Gen.module.globals:
                            func: Any = Gen.module.globals[MangledName]
                            if isinstance(func, ir.Function):
                                GlobalVar.initializer = func
                else:
                    if isinstance(VarType, ir.ArrayType) and isinstance(Node.value, (ast.List, ast.Set)):
                        InitConstants: list[ir.Constant] | None = self.Trans._BuildMultiDimArrayInitConstants(Node.value, VarType, Gen)
                        if InitConstants:
                            GlobalVar.initializer = ir.Constant(VarType, InitConstants)
                        else:
                            if self._contains_identified_struct(VarType):
                                GlobalVar.linkage = 'common'
                            else:
                                zv: ir.Constant | None = Gen._zero_value_for_type(VarType)
                                if zv:
                                    GlobalVar.initializer = zv
                                else:
                                    GlobalVar.linkage = 'common'
                    else:
                        init_val: ir.Constant | None = self._eval_global_const(Node.value, VarType, Gen)
                        if init_val:
                            GlobalVar.initializer = init_val
                        elif isinstance(VarType, ir.BaseStructType):
                            GlobalVar.linkage = 'common'
                        else:
                            GlobalVar.initializer = Gen._zero_value_for_type(VarType)
            else:
                if isinstance(VarType, ir.BaseStructType) or self._contains_identified_struct(VarType):
                    GlobalVar.linkage = 'common'
                else:
                    GlobalVar.initializer = Gen._zero_value_for_type(VarType)
            Gen.variables[VarName] = GlobalVar

    def _eval_global_const(self, value_node: ast.expr, var_type: ir.Type, Gen: "Translator.LlvmGen") -> ir.Constant | None:
        if isinstance(value_node, ast.Constant):
            if isinstance(value_node.value, bool):
                if isinstance(var_type, ir.IntType):
                    return ir.Constant(var_type, int(value_node.value))
            elif isinstance(value_node.value, int):
                if isinstance(var_type, ir.IntType):
                    return ir.Constant(var_type, value_node.value)
                elif isinstance(var_type, (ir.FloatType, ir.DoubleType)):
                    return ir.Constant(var_type, float(value_node.value))
            elif isinstance(value_node.value, float):
                if isinstance(var_type, (ir.FloatType, ir.DoubleType)):
                    return ir.Constant(var_type, value_node.value)
                elif isinstance(var_type, ir.IntType):
                    return ir.Constant(var_type, int(value_node.value))
            elif isinstance(value_node.value, str):
                return None
        # Handle type constructor calls like t.CDouble(1e-9), t.CFloat(3.14), t.CInt(42)
        if isinstance(value_node, ast.Call):
            inner_val: ir.Constant | None = self._eval_type_ctor_const(value_node, var_type, Gen)
            if inner_val is not None:
                return inner_val
        if isinstance(value_node, ast.UnaryOp) and isinstance(value_node.op, ast.USub):
            inner: ir.Constant | None = self._eval_global_const(value_node.operand, var_type, Gen)
            if inner:
                return ir.Constant(var_type, -inner.constant)
        # Handle enum member references like ASTVType.Module (ast.Attribute)
        if isinstance(value_node, ast.Attribute):
            attr_name: str = value_node.attr
            # 优先用带前缀的 key 查找（避免短名被同名函数/变量覆盖）
            if isinstance(value_node.value, ast.Name):
                FullKey2: str = f"{value_node.value.id}.{attr_name}"
                FullInfo: Any = self.Trans.SymbolTable.lookup(FullKey2)
                if FullInfo and FullInfo.IsEnumMember and isinstance(FullInfo.value, int):
                    if isinstance(var_type, ir.IntType):
                        return ir.Constant(var_type, FullInfo.value)
            SymInfo: Any = self.Trans.SymbolTable.lookup(attr_name)
            if SymInfo:
                if SymInfo.IsEnumMember and isinstance(SymInfo.value, int):
                    if isinstance(var_type, ir.IntType):
                        return ir.Constant(var_type, SymInfo.value)
        return None

    def _eval_type_ctor_const(self, call_node: ast.Call, var_type: ir.Type, Gen: "Translator.LlvmGen") -> ir.Constant | None:
        """Try to evaluate t.CDouble(val), t.CFloat(val), t.CInt(val) etc. as a compile-time constant."""
        if not isinstance(call_node.func, ast.Attribute):
            return None
        if not isinstance(call_node.func.value, ast.Name):
            return None
        if call_node.func.value.id != 't':
            return None
        if not call_node.args or len(call_node.args) != 1:
            return None
        arg: ast.expr = call_node.args[0]
        # Recursively evaluate the argument as a constant
        arg_val: ir.Constant | None = self._eval_global_const(arg, var_type, Gen)
        if arg_val is not None:
            return arg_val
        return None

    def _store_bitfield_member(self, struct_ptr: ir.Value, ClassName: str, field_name: str, Value: ir.Value) -> bool:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        bitfield_offsets: dict[str, int] = Gen.class_member_bitoffsets.get(ClassName, {})
        bitfield_widths: dict[str, int] = Gen.class_member_bitfields.get(ClassName, {})
        if field_name not in bitfield_offsets:
            return False
        bit_offset: int = bitfield_offsets[field_name]
        bit_width: int = bitfield_widths.get(field_name, 0)
        if bit_width == 0:
            return False
        struct_type: ir.Type | None = Gen.structs.get(ClassName)
        if struct_type is None or struct_type.elements is None or len(struct_type.elements) == 0:
            return False
        storage_type: ir.Type = struct_type.elements[0]
        member_ptr: ir.Value = Gen.builder.gep(struct_ptr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 0)], name=f"{field_name}_storage_ptr")
        old_val: ir.Value = Gen._load(member_ptr, name=f"{field_name}_old_storage")
        mask: int = (1 << bit_width) - 1
        shifted_mask: int = mask << bit_offset
        inverted_mask: ir.Constant = ir.Constant(storage_type, ~shifted_mask & ((1 << storage_type.width) - 1))
        cleared: ir.Value = Gen.builder.and_(old_val, inverted_mask, name=f"{field_name}_cleared")
        if isinstance(Value.type, ir.IntType) and Value.type.width < storage_type.width:
            if getattr(Value.type, 'is_signed', False):
                Value = Gen.builder.sext(Value, storage_type, name=f"{field_name}_sext_store")
            else:
                Value = Gen.builder.zext(Value, storage_type, name=f"{field_name}_zext_store")
        elif Value.type.width != storage_type.width:
            Value = Gen.builder.trunc(Value, storage_type, name=f"{field_name}_trunc_store") if Value.type.width > storage_type.width else Gen.builder.zext(Value, storage_type, name=f"{field_name}_zext_store")
        shifted_value: ir.Value = Gen.builder.shl(Value, ir.Constant(storage_type, bit_offset), name=f"{field_name}_shift_store")
        masked_value: ir.Value = Gen.builder.and_(shifted_value, ir.Constant(storage_type, shifted_mask), name=f"{field_name}_mask_store")
        new_val: ir.Value = Gen.builder.or_(cleared, masked_value, name=f"{field_name}_new_storage")
        Gen._store(new_val, member_ptr)
        return True

    def _CheckEnumMemberAssignment(self, node: ast.expr) -> str | None:
        def _get_attr_path(n: ast.expr) -> str | None:
            if isinstance(n, ast.Name):
                return n.id
            elif isinstance(n, ast.Attribute):
                return f"{_get_attr_path(n.value)}.{n.attr}"
            return None
        attr_path: str | None = _get_attr_path(node)
        if not attr_path:
            return None
        parts: list[str] = attr_path.split('.')
        if len(parts) >= 2:
            enum_class_name: str = parts[-2]
            member_name: str = parts[-1]
            qualified_name: str = f"{enum_class_name}.{member_name}"
            info: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(qualified_name)
            if info:
                if info.IsEnumMember and info.EnumName:
                    return info.EnumName
            under_name: str = f"{enum_class_name}_{member_name}"
            if self.Trans.SymbolTable.has(under_name):
                info: "SymbolTable.SymbolInfo" = self.Trans.SymbolTable[under_name]
                if info.IsEnumMember and info.EnumName:
                    return info.EnumName
            for key in self.Trans.SymbolTable:
                if key == member_name:
                    info: "SymbolTable.SymbolInfo" = self.Trans.SymbolTable[key]
                    if info.IsEnumMember and info.EnumName and info.EnumName == enum_class_name:
                        return enum_class_name
        return None

    def _IsTypedefAnnotation(self, annotation: ast.expr) -> bool:
        if isinstance(annotation, ast.Attribute):
            if annotation.attr in ('CTypedef', 'CDefine'):
                return True
        if isinstance(annotation, ast.BinOp) and isinstance(annotation.op, ast.BitOr):
            return self._IsTypedefAnnotation(annotation.left) or self._IsTypedefAnnotation(annotation.right)
        if isinstance(annotation, ast.Subscript):
            return self._IsTypedefAnnotation(annotation.value)
        return False

    def _EmitGlobalAssignLlvm(self, Node: ast.Assign, Gen: "Translator.LlvmGen") -> None:
        if len(Node.targets) == 1 and isinstance(Node.targets[0], ast.Name):
            VarName: str = Node.targets[0].id
            if VarName in Gen.variables or VarName in Gen.module.globals:
                return
            if isinstance(Node.value, ast.Call) and isinstance(Node.value.func, ast.Name):
                FuncName: str = Node.value.func.id
                if FuncName in Gen.structs:
                    IsUnion: bool = False
                    TypeInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(FuncName)
                    if TypeInfo:
                        if TypeInfo.IsUnion:
                            IsUnion = True
                    if IsUnion:
                        StructType: ir.Type = Gen.structs[FuncName]
                        StructPtrType: ir.PointerType = ir.PointerType(StructType)
                        GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, StructPtrType, name=VarName)
                        GlobalVar.initializer = ir.Constant(StructPtrType, None)
                        Gen.variables[VarName] = GlobalVar
                        Gen.global_struct_class[VarName] = FuncName
                        return
                    StructName: str = FuncName
                    VarType: ir.Type = Gen.structs[StructName]
                    GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VarType, name=VarName)
                    const: ir.Constant | None = self.Trans.ClassHandler._BuildStructConstant(Node.value, StructName, Gen)
                    if const:
                        GlobalVar.initializer = const
                    else:
                        GlobalVar.linkage = 'common'
                    Gen.variables[VarName] = GlobalVar
                    Gen.global_struct_class[VarName] = StructName
                    return
            GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, ir.IntType(32), name=VarName)
            init_val: ir.Constant | None = self._eval_global_const(Node.value, ir.IntType(32), Gen)
            GlobalVar.initializer = init_val if init_val else ir.Constant(ir.IntType(32), 0)
            Gen.variables[VarName] = GlobalVar

    def _eval_const_expr(self, node: ast.expr, Gen: "Translator.LlvmGen") -> int | float | None:
        """计算常量表达式的值（委托到 ConstEvaluator）"""
        ctx: EvalContext = EvalContext(Gen=Gen, symtab=self.Trans.SymbolTable, translator=self.Trans)
        return ConstEvaluator.eval_full(node, ctx)

    def _eval_global_count(self, node: ast.expr, Gen: "Translator.LlvmGen") -> int | None:
        val: int | float | None = self._eval_const_expr(node, Gen)
        if val is not None:
            if isinstance(val, float):
                return int(val)
            if isinstance(val, int):
                return val
        return None