from __future__ import annotations

import ast
import re
import llvmlite.ir as ir

from lib.core.LlvmCodeGenerator import LlvmCodeGenerator
from lib.core.Handles.HandlesBase import CTypeInfo
from lib.core.Handles.HandlesBase import CTypeInfo as _CTypeInfo, CTypeHelper
from lib.includes import t
from lib.constants.config import mode as _config_mode
from lib.core.VLogger import get_logger as _vlog
from lib.core.DecoratorPass import run as _run_decorator_pass
from lib.core.SymbolUtils import IsTModule, AnnotationContainsName


class LlvmGeneratorMixin:
    """LLVM IR 生成 Mixin

    提供 LLVM IR 直接生成、模块级 LLVM IR 处理与 C 代码生成入口能力。
    """

    def GenerateLlvmDirect(self, Tree: ast.Module) -> str:
        Gen: LlvmCodeGenerator = self.LlvmGen

        # === 新增：轻量 AST 遍历，收集类图信息，解决前向引用 ===
        Gen._class_graph: dict[str, dict[str, bool | list[str]]] = {}
        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.ClassDef):
                bases: list[str] = []
                for base in Node.bases:
                    if hasattr(base, 'id'):
                        bases.append(base.id)
                    elif hasattr(base, 'attr'):
                        bases.append(base.attr)
                has_methods: bool = any(isinstance(item, ast.FunctionDef) for item in Node.body)
                # 检测 @t.NoVTable 装饰器（非多态继承基类标记）
                has_novtable: bool = False
                if hasattr(Node, 'decorator_list') and Node.decorator_list:
                    for decorator in Node.decorator_list:
                        if isinstance(decorator, ast.Attribute):
                            if getattr(decorator.value, 'id', None) == 't' and decorator.attr == 'NoVTable':
                                has_novtable = True
                        elif isinstance(decorator, ast.Name):
                            if decorator.id == 'NoVTable':
                                has_novtable = True
                Gen._class_graph[Node.name] = {
                    'bases': bases,
                    'has_methods': has_methods,
                    'has_novtable': has_novtable,
                }
        # === 结束新增 ===

        # 预扫描：为所有 -> str 注解的函数注册正确的返回类型 i8*
        # 这样在类方法中调用这些函数时，前向声明会使用正确的类型
        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.FunctionDef):
                if Node.returns and isinstance(Node.returns, ast.Name) and Node.returns.id == 'str':
                    Gen.known_return_types[Node.name] = ir.PointerType(ir.IntType(8))

        # 首先收集所有 CDefine 常量，确保类定义中可以引用
        def _extract_call_const_val(node: ast.AST) -> int | str | float | None:
            if isinstance(node, ast.Call):
                if isinstance(node.func, ast.Attribute):
                    if getattr(node.func.value, 'id', None) == 't':
                        if node.args and isinstance(node.args[0], ast.Constant):
                            return node.args[0].value
                elif isinstance(node.func, ast.Name):
                    if node.args and isinstance(node.args[0], ast.Constant):
                        return node.args[0].value
            return None

        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.AnnAssign) and isinstance(Node.target, ast.Name) and Node.value:
                TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(Node.annotation)
                if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine)):
                    val: int | str | float | None = None
                    if isinstance(Node.value, ast.Constant):
                        val = Node.value.value
                    else:
                        val = _extract_call_const_val(Node.value)
                    if val is not None:
                        if not hasattr(Gen, '_define_constants'):
                            Gen._define_constants: dict[str, int | str | float | bool] = {}
                        Gen._define_constants[Node.target.id] = val
                        existing = self.SymbolTable.lookup(Node.target.id)
                        if not (existing and existing.IsTypedef and existing.OriginalType):
                            sym_info: _CTypeInfo = _CTypeInfo()
                            sym_info.IsDefine = True
                            sym_info.DefineValue = val
                            self.SymbolTable.insert(Node.target.id, sym_info)
            elif isinstance(Node, ast.Assign):
                for target in Node.targets:
                    if isinstance(target, ast.Name):
                        TypeInfo: CTypeInfo | None = None
                        if Node.type_comment:
                            try:
                                tc_ast: ast.Expression = ast.parse(Node.type_comment, mode='eval')
                                TypeInfo = self.TypeMergeHandler.GetCTypeInfo(tc_ast.body)
                            except Exception as _e:
                                if _config_mode == "strict":
                                    raise
                                _vlog().warning(f"解析类型注释失败: {_e}", "Exception")
                        if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine)):
                            val: int | str | float | None = None
                            if isinstance(Node.value, ast.Constant):
                                val = Node.value.value
                            else:
                                val = _extract_call_const_val(Node.value)
                            if val is not None:
                                if not hasattr(Gen, '_define_constants'):
                                    Gen._define_constants: dict[str, int | str | float | bool] = {}
                                Gen._define_constants[target.id] = val
                                sym_info: _CTypeInfo = _CTypeInfo()
                                sym_info.IsDefine = True
                                sym_info.DefineValue = val
                                self.SymbolTable.insert(target.id, sym_info)

        # 预扫描所有顶层函数定义，填充 FunctionDefCache（不创建 LLVM 声明）
        # 这样类方法编译时遇到未声明的函数可以按需前向声明
        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.FunctionDef):
                FuncName: str = Node.name
                if FuncName not in self.FunctionDefCache:
                    self.FunctionDefCache[FuncName] = Node

        # 首先处理所有导入语句，确保模块在类型解析前被加载
        for Node in ast.iter_child_nodes(Tree):
            Gen._set_node_info(Node)
            try:
                if isinstance(Node, ast.Import):
                    self.ImportHandler._EmitImportDeclarationsLlvm(Node, Gen)
                elif isinstance(Node, ast.ImportFrom):
                    self.ImportHandler._EmitImportFromDeclarationsLlvm(Node, Gen)
            except Exception as e:
                lineno: int = getattr(Node, 'lineno', 0)
                source_line: str | None = Gen._get_source_line(lineno)
                src_file: str = getattr(Gen, '_current_source_file', '')
                src_path: str = src_file if src_file else 'unknown'
                line_info: str = "源代码 (%s, line %d)" % (src_path, lineno)
                if source_line:
                    line_info += ":\n    %d | %s" % (lineno, source_line)
                self._ErrorStack.append((type(e).__name__, str(e), line_info))

        # 前向声明所有顶层函数，确保全局变量初始化时能引用函数指针
        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.FunctionDef):
                Gen._set_node_info(Node)
                self.FunctionHandler._EmitFunctionForwardDeclLlvm(Node, Gen)

        # 预创建全局变量（带初始化器），确保类方法编译时能引用全局数组等
        Gen._current_tree: ast.Module = Tree
        for Node in ast.iter_child_nodes(Tree):
            Gen._set_node_info(Node)
            if isinstance(Node, ast.AnnAssign):
                self.AssignHandler._EmitGlobalAnnAssignLlvm(Node, Gen)
            elif isinstance(Node, ast.Assign):
                self.AssignHandler._EmitGlobalAssignLlvm(Node, Gen)

        # 首先处理所有类定义（包括 CUnion），确保类型定义在使用前完成
        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.ClassDef):
                Gen._set_node_info(Node)
                self.ClassHandler._EmitClassLlvm(Node, Gen)

        Gen._generate_structs()
        Gen._create_Vtable_globals()

        for Node in ast.iter_child_nodes(Tree):
            Gen._set_node_info(Node)
            try:
                if isinstance(Node, ast.Import):
                    continue
                elif isinstance(Node, ast.ImportFrom):
                    continue
                elif isinstance(Node, ast.ClassDef):
                    continue
                elif isinstance(Node, ast.FunctionDef):
                    self.FunctionHandler._EmitFunctionLlvm(Node, Gen)
                elif isinstance(Node, ast.AnnAssign):
                    self.AssignHandler._EmitGlobalAnnAssignLlvm(Node, Gen)
                elif isinstance(Node, ast.Assign):
                    self.AssignHandler._EmitGlobalAssignLlvm(Node, Gen)
                elif isinstance(Node, ast.If):
                    pass
                elif isinstance(Node, ast.Expr):
                    self._HandleModuleLevelExprLlvm(Node, Gen)
            except Exception as e:
                lineno: int = getattr(Node, 'lineno', 0)
                source_line: str | None = Gen._get_source_line(lineno)
                src_file: str = getattr(Gen, '_current_source_file', '')
                src_path: str = src_file if src_file else 'unknown'
                line_info: str = "源代码 (%s, line %d)" % (src_path, lineno)
                if source_line:
                    line_info += ":\n    %d | %s" % (lineno, source_line)
                self._ErrorStack.append((type(e).__name__, str(e), line_info))
                raise
        Gen._set_Vtable_initializers()
        # 执行 DecoratorPass：为带自定义装饰器的函数生成 wrapper
        _run_decorator_pass(Gen)
        ir_code: str = Gen.finalize()
        return ir_code

    def _HandleModuleLevelExprLlvm(self, Node: ast.Expr, Gen: LlvmCodeGenerator) -> None:
        if not isinstance(Node.value, ast.Call):
            return
        call: ast.Call = Node.value
        if not isinstance(call.func, ast.Attribute):
            return
        if not isinstance(call.func.value, ast.Name) or call.func.value.id != 'c':
            return
        func_name: str = call.func.attr
        if func_name == 'LLVMIR':
            self._HandleModuleLevelLLVMIR(call, Gen)

    def _HandleModuleLevelLLVMIR(self, Node: ast.Call, Gen: LlvmCodeGenerator) -> None:
        if not Node.args:
            return
        first_arg: ast.expr = Node.args[0]
        if isinstance(first_arg, ast.Constant) and isinstance(first_arg.value, str):
            ir_text: str = first_arg.value
        elif isinstance(first_arg, ast.JoinedStr):
            parts: list[str] = []
            for value in first_arg.values:
                if isinstance(value, ast.Constant) and isinstance(value.value, str):
                    parts.append(value.value)
                elif isinstance(value, ast.FormattedValue):
                    parts.append('')
            ir_text = ''.join(parts)
        else:
            return
        self._InsertModuleLevelLLVMIR(Gen, ir_text)

    def _InsertModuleLevelLLVMIR(self, Gen: LlvmCodeGenerator, ir_text: str) -> None:
        for line in ir_text.strip().split('\n'):
            line = line.strip()
            if not line:
                continue
            module_flags_match: re.Match[str] | None = re.match(r'!llvm\.module\.flags\s*=\s*!\{(!\d+)\}', line)
            if module_flags_match:
                ref: str = module_flags_match.group(1)
                if not hasattr(Gen, '_pending_module_flags'):
                    Gen._pending_module_flags: list = []
                Gen._pending_module_flags_refs: str = ref
                continue
            metadata_match: re.Match[str] | None = re.match(r'(!\d+)\s*=\s*!\{(.+)\}', line)
            if metadata_match:
                md_id: str = metadata_match.group(1)
                md_body: str = metadata_match.group(2)
                fields: list[ir.Constant | ir.MetaDataString | str] = []
                for field_str in re.split(r',\s*', md_body):
                    field_str = field_str.strip()
                    if not field_str:
                        continue
                    int_m: re.Match[str] | None = re.match(r'^i32\s+(\d+)$', field_str)
                    if int_m:
                        fields.append(ir.Constant(ir.IntType(32), int(int_m.group(1))))
                        continue
                    str_m: re.Match[str] | None = re.match(r'^"([^"]*)"$', field_str)
                    if str_m:
                        fields.append(ir.MetaDataString(Gen.module, str_m.group(1)))
                        continue
                    mdstr_m: re.Match[str] | None = re.match(r'^!"([^"]*)"$', field_str)
                    if mdstr_m:
                        fields.append(ir.MetaDataString(Gen.module, mdstr_m.group(1)))
                        continue
                    int_m2: re.Match[str] | None = re.match(r'^(\d+)$', field_str)
                    if int_m2:
                        fields.append(ir.Constant(ir.IntType(32), int(int_m2.group(1))))
                        continue
                    ref_m: re.Match[str] | None = re.match(r'^(!\d+)$', field_str)
                    if ref_m:
                        fields.append(ref_m.group(1))
                        continue
                if fields:
                    if not hasattr(Gen, '_pending_metadata'):
                        Gen._pending_metadata: list[tuple[str, list]] = []
                    Gen._pending_metadata.append((md_id, fields))
                continue
        self._FlushModuleMetadata(Gen)

    def _FlushModuleMetadata(self, Gen: LlvmCodeGenerator) -> None:
        if not hasattr(Gen, '_pending_metadata') or not Gen._pending_metadata:
            return
        md_map: dict[str, ir.MetaDataString] = {}
        for md_id, fields in Gen._pending_metadata:
            resolved: list[ir.Constant | ir.MetaDataString] = []
            for f in fields:
                if isinstance(f, str) and f.startswith('!'):
                    ref: ir.MetaDataString | None = md_map.get(f)
                    if ref:
                        resolved.append(ref)
                else:
                    resolved.append(f)
            md_value: ir.MetaDataString = Gen.module.add_metadata(resolved)
            md_map[md_id] = md_value
        if hasattr(Gen, '_pending_module_flags_refs'):
            ref: str = Gen._pending_module_flags_refs
            md_node: ir.MetaDataString | None = md_map.get(ref)
            if md_node:
                Gen.module.add_named_metadata('llvm.module.flags', md_node)
        Gen._pending_metadata = []
        Gen._pending_module_flags_refs = None

    def GenerateCCode(self, Tree: ast.Module, target: str = 'llvm') -> str:
        """生成代码

        Args:
            Tree: Python AST 树
            target: 目标代码类型，仅支持 'llvm'

        Returns:
            生成的代码字符串
        """
        self._generated_vars: set[str] = set()
        self.VarScopes = [{}]  # 全局作用域

        # 预扫描 import 语句，注册别名，确保类型解析时能正确解析模块别名
        if not getattr(self, '_ImportedModules', None):
            self._ImportedModules: set[str] = set()
        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.Import):
                for alias in Node.names:
                    name: str = alias.name
                    if name in ('c', 't'):
                        continue
                    self._ImportedModules.add(name)
                    if alias.asname:
                        self.SymbolTable.import_aliases[alias.asname] = name
            elif isinstance(Node, ast.ImportFrom):
                module_name: str | None = Node.module
                if module_name and module_name not in ('c', 't'):
                    self._ImportedModules.add(module_name)
                    for alias in Node.names:
                        if alias.asname:
                            self.SymbolTable.import_aliases[alias.asname] = f"{module_name}.{alias.name}"

        for Node in ast.iter_child_nodes(Tree):
            if isinstance(Node, ast.ClassDef):
                ClassName: str = Node.name

                # 检查是否是特殊类型（枚举或联合体）
                IsSpecialType: bool = False
                if Node.bases:
                    for base in Node.bases:
                        if hasattr(base, 'attr'):
                            if base.attr in ['CEnum', 'Enum', 'CUnion', 'REnum']:
                                IsSpecialType = True
                                break
                        elif hasattr(base, 'id'):
                            if base.id in ['CEnum', 'Enum', 'CUnion', 'REnum']:
                                IsSpecialType = True
                                break

                # 如果是特殊类型，跳过这里的处理（由 HandleClassDef 处理）
                if IsSpecialType:
                    continue

                members: dict[str, CTypeInfo] = {}
                IsTypedef: bool = False
                TypedefName: str | None = None

                if hasattr(Node, 'annotation') and Node.annotation:
                    try:
                        if AnnotationContainsName(Node.annotation, 'CTypedef'):
                            IsTypedef = True
                            if isinstance(Node.annotation, ast.Call):
                                if Node.annotation.args:
                                    if isinstance(Node.annotation.args[0], ast.Constant):
                                        TypedefName = Node.annotation.args[0].value
                    except Exception as _e:
                        if _config_mode == "strict":
                            raise
                        _vlog().warning(f"解析 typedef 注解失败: {_e}", "Exception")

                if not IsTypedef:
                    for item in Node.body:
                        if isinstance(item, ast.Assign):
                            for target in item.targets:
                                if isinstance(target, ast.Name) and target.id == '__annotations__':
                                    if isinstance(item.value, ast.Dict):
                                        for key, value in zip(item.value.keys, item.value.values):
                                            if isinstance(key, ast.Constant) and key.value == '__type__':
                                                if AnnotationContainsName(value, 'CTypedef'):
                                                    IsTypedef = True

                if IsTypedef:
                    TypedefKey: str = TypedefName if TypedefName else ClassName
                    TypedefNode: CTypeInfo = CTypeInfo()
                    TypedefNode.Name = TypedefKey
                    TypedefNode.IsTypedef = True
                    TypedefNode.OriginalType = f'struct {ClassName}'
                    TypedefNode.set('IsComplete', True)
                    TypedefNode.file = '<stdin>'
                    self.SymbolTable.insert(TypedefKey, TypedefNode)

                for item in Node.body:
                    if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
                        VarName: str = item.target.id
                        try:
                            TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(item.annotation)
                            if TypeInfo is None:
                                TypeInfo = CTypeInfo()
                                TypeInfo.BaseType = t.CInt()
                            IsPtr: bool = TypeInfo.IsPtr
                            if not IsPtr:
                                if isinstance(item.annotation, ast.BinOp) and isinstance(item.annotation.op, ast.BitOr):
                                    if AnnotationContainsName(item.annotation, 'CPtr'):
                                        IsPtr = True
                            dims: list[int] = []
                            if hasattr(item.annotation, 'slice') and isinstance(item.annotation.slice, ast.Constant):
                                if isinstance(item.annotation.value, ast.Name):
                                    if IsTModule(item.annotation.value.id, self.SymbolTable):
                                        if hasattr(item.annotation, 'slice'):
                                            try:
                                                dims.append(int(item.annotation.slice.value))
                                            except Exception as _e:
                                                if _config_mode == "strict":
                                                    self.LogWarning(f"异常被忽略: {_e}")
                            MemberInfo: CTypeInfo = TypeInfo.Copy()
                            if dims:
                                MemberInfo.ArrayDims = [str(d) for d in dims]
                            members[VarName] = MemberInfo
                        except Exception as _e:
                            if _config_mode == "strict":
                                self.LogWarning(f"异常被忽略: {_e}")

                if not IsTypedef:
                    StructNode: CTypeInfo = CTypeInfo()
                    StructNode.Name = ClassName
                    StructNode.IsStruct = True
                    StructNode.Members = members or {}
                    StructNode.file = '<stdin>'
                    existing: CTypeInfo | None = self.SymbolTable.lookup(ClassName)
                    if existing:
                        if hasattr(existing, 'IsCpythonObject') and existing.IsCpythonObject:
                            StructNode.IsCpythonObject = True
                    self.SymbolTable.insert(ClassName, StructNode)
            elif isinstance(Node, ast.FunctionDef):
                FuncName: str = Node.name
                if not self.SymbolTable.has(FuncName):
                    FuncNode: CTypeInfo = CTypeInfo()
                    FuncNode.Name = FuncName
                    FuncNode.IsFunction = True
                    FuncNode.file = '<stdin>'
                    self.SymbolTable.insert(FuncName, FuncNode)
            elif isinstance(Node, ast.AnnAssign):
                if isinstance(Node.target, ast.Name):
                    VarName: str = Node.target.id

                    VarType: str = 'unknown'
                    IsPtr: bool = False
                    IsTypedef_assignment: bool = False

                    if Node.annotation:
                        try:
                            if AnnotationContainsName(Node.annotation, 'CTypedef'):
                                IsTypedef_assignment = True
                        except Exception as _e:
                            if _config_mode == "strict":
                                self.LogWarning(f"异常被忽略: {_e}")

                    if IsTypedef_assignment and Node.value:
                        if isinstance(Node.value, ast.Name):
                            OriginalType: str = Node.value.id
                            if OriginalType in self.GeneratedTypes:
                                OriginalInfo: CTypeInfo | None = self.SymbolTable.lookup(OriginalType)
                                if OriginalInfo:
                                    if isinstance(OriginalInfo, dict):
                                        actual_type: str = OriginalInfo.get('type', 'struct')
                                    elif isinstance(OriginalInfo, CTypeInfo):
                                        if OriginalInfo.IsEnum:
                                            actual_type = 'enum'
                                        elif OriginalInfo.IsTypedef:
                                            actual_type = 'typedef'
                                        elif OriginalInfo.IsStruct:
                                            actual_type = 'struct'
                                        else:
                                            actual_type = 'struct'
                                    else:
                                        actual_type = 'struct'
                                    if actual_type == 'enum':
                                        TypedefNode: CTypeInfo = CTypeInfo()
                                        TypedefNode.Name = VarName
                                        TypedefNode.IsTypedef = True
                                        TypedefNode.OriginalType = f'enum {OriginalType}'
                                        TypedefNode.file = '<stdin>'
                                        self.SymbolTable.insert(VarName, TypedefNode)
                                    elif actual_type == 'typedef':
                                        TypedefNode = CTypeInfo()
                                        TypedefNode.Name = VarName
                                        TypedefNode.IsTypedef = True
                                        if isinstance(OriginalInfo, dict):
                                            TypedefNode.OriginalType = OriginalInfo.get('OriginalType', f'struct {OriginalType}')
                                        elif isinstance(OriginalInfo, CTypeInfo) and OriginalInfo.OriginalType:
                                            TypedefNode.OriginalType = OriginalInfo.OriginalType
                                        else:
                                            TypedefNode.OriginalType = f'struct {OriginalType}'
                                        TypedefNode.file = '<stdin>'
                                        self.SymbolTable.insert(VarName, TypedefNode)
                                    else:
                                        TypedefNode = CTypeInfo()
                                        TypedefNode.Name = VarName
                                        TypedefNode.IsTypedef = True
                                        TypedefNode.OriginalType = f'struct {OriginalType}'
                                        TypedefNode.file = '<stdin>'
                                        self.SymbolTable.insert(VarName, TypedefNode)
                                    self.GeneratedTypes.add(VarName)
                                    continue
                            else:
                                OriginalInfo: CTypeInfo | None = self.SymbolTable.lookup(OriginalType)
                                if OriginalInfo:
                                    if isinstance(OriginalInfo, dict):
                                        actual_type: str = OriginalInfo.get('type', 'struct')
                                    elif isinstance(OriginalInfo, CTypeInfo):
                                        if OriginalInfo.IsEnum:
                                            actual_type = 'enum'
                                        elif OriginalInfo.IsTypedef:
                                            actual_type = 'typedef'
                                        elif OriginalInfo.IsStruct:
                                            actual_type = 'struct'
                                        else:
                                            actual_type = 'struct'
                                    else:
                                        actual_type = 'struct'
                                    if actual_type == 'typedef':
                                        TypedefNode: CTypeInfo = CTypeInfo()
                                        TypedefNode.Name = VarName
                                        TypedefNode.IsTypedef = True
                                        if isinstance(OriginalInfo, dict):
                                            TypedefNode.OriginalType = OriginalInfo.get('OriginalType', f'struct {OriginalType}')
                                        elif isinstance(OriginalInfo, CTypeInfo) and OriginalInfo.OriginalType:
                                            TypedefNode.OriginalType = OriginalInfo.OriginalType
                                        else:
                                            TypedefNode.OriginalType = f'struct {OriginalType}'
                                        TypedefNode.file = '<stdin>'
                                        self.SymbolTable.insert(VarName, TypedefNode)
                                        self.GeneratedTypes.add(VarName)
                                        if isinstance(OriginalInfo, dict):
                                            OriginalInfo['skip_generation'] = True
                                        continue
                                    elif actual_type == 'struct':
                                        TypedefNode = CTypeInfo()
                                        TypedefNode.Name = VarName
                                        TypedefNode.IsTypedef = True
                                        TypedefNode.OriginalType = f'struct {OriginalType}'
                                        TypedefNode.file = '<stdin>'
                                        self.SymbolTable.insert(VarName, TypedefNode)
                                        self.GeneratedTypes.add(VarName)
                                        if isinstance(OriginalInfo, dict):
                                            OriginalInfo['skip_generation'] = True
                                        continue
                                    elif actual_type == 'enum':
                                        TypedefNode = CTypeInfo()
                                        TypedefNode.Name = VarName
                                        TypedefNode.IsTypedef = True
                                        TypedefNode.OriginalType = f'enum {OriginalType}'
                                        TypedefNode.file = '<stdin>'
                                        self.SymbolTable.insert(VarName, TypedefNode)
                                        self.GeneratedTypes.add(VarName)
                                        if isinstance(OriginalInfo, dict):
                                            OriginalInfo['skip_generation'] = True
                                        continue
                        elif isinstance(Node.value, ast.Attribute):
                            CName: str | None = CTypeHelper.GetCName(Node.value.attr)
                            if CName:
                                TypedefNode: CTypeInfo = CTypeInfo()
                                TypedefNode.Name = VarName
                                TypedefNode.IsTypedef = True
                                TypedefNode.OriginalType = CName
                                TypedefNode.file = '<stdin>'
                                self.SymbolTable.insert(VarName, TypedefNode)
                                self.GeneratedTypes.add(VarName)
                                continue

                    if Node.annotation:
                        try:
                            TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(Node.annotation)
                            IsPtr = TypeInfo.IsPtr if TypeInfo else False
                        except Exception as _e:
                            if _config_mode == "strict":
                                self.LogWarning(f"异常被忽略: {_e}")
                    # 如果符号已经存在且是 typedef，不要覆盖它
                    existing = self.SymbolTable.lookup(VarName)
                    if existing and existing.IsTypedef and existing.OriginalType:
                        # typedef 已正确插入，保持现有条目不覆盖
                        pass
                    else:
                        var_node: CTypeInfo = CTypeInfo()
                        var_node.Name = VarName
                        var_node.IsVariable = True
                        var_node.PtrCount = 1 if IsPtr else 0
                        var_node.file = '<stdin>'
                        self.SymbolTable.insert(VarName, var_node)

        self.LlvmGen: LlvmCodeGenerator = LlvmCodeGenerator(
            triple=getattr(self, 'triple', None),
            datalayout=getattr(self, 'datalayout', None),
        )
        self.LlvmGen._Trans = self
        self.LlvmGen._import_handler_ref = self.ImportHandler
        if hasattr(self, '_module_sha1'):
            self.LlvmGen.module_sha1 = self._module_sha1
        if hasattr(self, '_ModuleSha1Map'):
            self.LlvmGen.ModuleSha1Map = self._ModuleSha1Map
        if hasattr(self, '_struct_sha1_map'):
            self.LlvmGen._struct_sha1_map = self._struct_sha1_map
        if hasattr(self, '_temp_dir'):
            self.LlvmGen._temp_dir = self._temp_dir
        if hasattr(self, '_export_extern_funcs'):
            self.LlvmGen._export_extern_funcs = self._export_extern_funcs
        self.LlvmGen.setup_from_symbol_table(self.SymbolTable)
        if hasattr(self, 'CurrentFile') and self.CurrentFile:
            self.LlvmGen._set_source_info(self.CurrentFile)

        # --- 修复：共享 vtable 状态跨模块 ---
        # 根因：LlvmGen 每模块重新创建，class_vtable/class_methods 等是实例级属性，
        # 不跨模块共享。导致模块 B 编译时 _specialize_generic_class 触发的
        # pool.alloc(48) 找不到 MemManager 的虚表状态，直接调用 stub 返回 NULL → 段错误。
        # 修复：将 vtable 状态存储在 Translator 对象上并赋值给每个新 Gen。
        if not hasattr(self, '_shared_class_vtable'):
            self._shared_class_vtable: set[str] = set()
            self._shared_cross_module_vtable: set[str] = set()
            self._shared_class_methods: dict[str, list[str]] = {}
            self._shared_cross_module_novtable: set[str] = set()
        # 合并 setup_from_symbol_table 创建的实例级 class_methods 到共享 dict
        # （仅添加新类，不覆盖已有方法列表）
        for _cls_name, _methods in self.LlvmGen.class_methods.items():
            if _cls_name not in self._shared_class_methods:
                self._shared_class_methods[_cls_name] = _methods
            else:
                for _m in _methods:
                    if _m not in self._shared_class_methods[_cls_name]:
                        self._shared_class_methods[_cls_name].append(_m)
        # 替换为共享状态
        self.LlvmGen.class_vtable = self._shared_class_vtable
        self.LlvmGen._cross_module_vtable_classes = self._shared_cross_module_vtable
        self.LlvmGen.class_methods = self._shared_class_methods
        self.LlvmGen._cross_module_novtable = self._shared_cross_module_novtable
        # --- 修复结束 ---

        return self.GenerateLlvmDirect(Tree)
