将 node 追加为 self 的最后一个子节点（O(1)）。

        若 node 已在某链表中，调用方应先 node.detach() 再 append。
        
将 self 从其所在兄弟链表中摘除（O(1)）。

        调用后 self 的 Next/Prev/Parent 被清空，Child 链不受影响。
        
堆上动态列表容器，基于 memhub.MemManager 多态分配器。

    用法:
        pool: memhub.MemManager = memhub.MemBuddy(arena, arena_size)
        nums: list[int] = list[int](pool)
        nums.append(42)
        x: int = nums.get(0)

    对于指针类型（如 AST | t.CPtr），传 elem_size=8 避免对象切片:
        lst: list[AST | t.CPtr] = list[AST | t.CPtr](pool, 8)
    
遍历 tree.children 并翻译每个子节点

    Args:
        trans: 翻译器（含所有共享状态）
        tree: AST 模块节点

    Returns:
        t.CInt: 新增的变量数
    
创建包装 main 函数并翻译所有顶层语句

    Args:
        i32_ty: i32 LLVMType

    Returns:
    
如果 name 是泛型类型参数，返回对应的具体类型名；否则返回 name 本身

    用于表达式中的 T 替换（如 T.__sizeof__() → int.__sizeof__()）
    
将 t.CXxx / c.CXxx 类型名映射到 LLVMType

    注意: t.CChar | t.CPtr = i8* = str = bytes
    
解析类型注解节点为 LLVMType

    Args:
        pool: 内存分配器
        node: 类型注解 AST 节点（Name 或 Attribute）
        imported_modules: 已导入模块名字符串（空格分隔）
        from_imports: from-import 映射字符串（"name:module name:module" 格式）
    
推断表达式的 LLVM 类型

    param_types 格式: "name:bits,name:bits,..."
    
将 LLVM IR 输出到缓冲区

        mode: 0=完整, 1=stub(仅声明), 2=text(仅代码)
        
根据目标三元组配置平台相关类型的大小

    Args:
        triple: LLVM 目标三元组字符串，如 'x86_64-pc-windows-gnu'
    
设置默认值/初始值，用于 static/global 变量的初始化

        Args:
            **kwargs: 成员名称和值的键值对

        Returns:
            包含默认值信息的 CTypeDefault 对象
        
获取完整的类型声明字符串

        Args:
            VarName: 变量名
            ArraySizeStr: 数组大小字符串

        Returns:
            完整的类型声明字符串
        
标记类为非多态继承基类：被子类继承时字段直接展平嵌入，不生成 vtable，避免 vtable 开销。
    区别于 @t.CVTable（启用多态 vtable）。对应 C++ 的非多态继承（struct A : B {} 无 virtual）。

标记函数为 TLS 初始化函数，首次调用时执行，后续调用跳过。
    编译器自动生成全局标志变量和一次性执行检查代码。
    
函数签名注解：自动取地址（仅对非指针值）。
    用作参数类型时，编译器在调用处自动将非指针值取地址为指针。
    若参数已经是指针，则不做操作。

函数签名注解：无条件取地址。
    用作参数类型时，编译器在调用处无条件将值取地址为指针，
    即使值本身已经是指针也会再取一层地址。

用于存储 C 类型默认值/初始化的包装类

    当使用 t.CStatic.__set_default__(open=mouse_open, ...) 时创建
    
栈上固定数组类型注解。
    用法: names: t.CArray[VOIDPTR, 32]  # void*[32]
          data: t.CArray[t.CInt, 64]    # int[64]
    第一个参数为元素类型，第二个参数为数组大小（整数或常量名）。

大端序（Big-Endian）字节序标记类
    
    用于标记结构体成员应使用大端序存储。
    在小端序平台（如x86）上读取时，会自动进行字节交换。
    
    用法示例：
        class MyStruct:
            a: t.CInt | t.BigEndian  # 大端序存储的整数
    
小端序（Little-Endian）字节序标记类

    用于标记结构体成员应使用小端序存储。
    在小端序平台（如x86）上读取时，不需要进行字节交换。

    用法示例：
            b: t.CInt | t.LittleEndian  # 小端序存储的整数
    
基于 CType 元属性的类型注册表，替代手动映射表
    
    利用 CType 子类的 position/IsSigned/Size 元属性自动推导：
    - LLVM IR 类型字符串 (如 'i32', 'double', 'i8*')
    - C 类型名称 (如 'int', 'unsigned char', 'long long')
    - Python CType 类引用 (如 t.CInt32T)
    
从 CType 类的元属性推导 LLVM IR 类型字符串
        
        规则:
        - position 含 POINTER 且不含 BASE → 'i8*'
        - position 含 PREFIX 且不含 BASE → '' (修饰符,无LLVM类型)
        - Size == 0 且 IsSigned is None → 'void'
        - IsSigned is None 且 Size > 0 → 浮点: half/float/double/fp128
        - IsSigned is True/False 且 Size > 0 → 整数: i{Size}
        
根据 Python 类型名推导 LLVM IR 类型 (如 'CFloat64T' -> 'double')
        
        修饰符类型 (CConst, CStatic 等) 返回空字符串。
        指针类型 (CPtr) 返回 'i8*'。
        未知类型返回 None。
        
解析类型名到 (CType类, 指针层级)

        支持的格式:
        - Python 类名: 'CInt32T' -> (t.CInt32T, 0)
        - C 基本类型名/Python 内置名: 'int' -> (t.CInt, 0), 'bool' -> (t.CBool, 0)

        注意：stdint.h 类型名（int8_t/uint8_t/size_t/intptr_t 等）和
        Win32 大写别名（INT8/UINT8/BYTE/DWORD/FLOAT8 等）由 stdint.py
        通过 t.CTypedef 提供，用户 `from stdint import *` 后即可使用。

        指针必须使用 t.CPtr[T] 显式表达（如 t.CPtr[t.CInt]），
        本方法不再做 PTR 后缀的隐式类型推断，以避免违反类型自由原则。
        
从 AST 节点提取属性名

    支持:
    - Call(func=Attribute(...)): t.attr.always_inline() -> "always_inline"
    - Attribute: t.attr.packed -> "packed"
    - Attribute(t.attr.llvm.xxx): t.attr.llvm.nounwind -> "nounwind"
    
加载工程配置文件（project.vpj）

    Args:
        path: 配置文件路径

    Returns:
        0 表示成功，非 0 表示失败
    
将 JSON 字符串数组拼接成空格分隔的字符串

    用于 linker.flags 和 compiler.flags 数组。
    用 while + 索引遍历，避免 list 迭代器 bug。

    Args:
        flags_val: JsonValue，应为字符串数组

    Returns:
        空格分隔的字符串，或 None 如果 flags_val 为 None 或非数组或空数组
    
将相对路径与 project_dir 拼接为绝对路径

    - ./App + Test → Test/App
    - ./temp + Test → Test/temp
    - ../includes + Test → Test/../includes（OS 解析为 includes）
    - 绝对路径保持不变
    - None 返回 None
    
解析并规范化工程路径（src/temp/output/includes）

    将 project.vpj 中的相对路径（以 ./ 开头）转换为基于 project_dir 的路径。

    Args:
        project_dir: 工程根目录（project.vpj 所在目录）

    Returns:
    
获取 includes.binary 目录路径（includes 目录 + .binary 后缀）

    includes 目录如 ../includes，则 includes.binary 为 ../includes.binary
    
重置可见性状态（每个文件翻译前调用）

    pool: 内存分配器（严格模式下创建 HashTable）
    strict: 1=严格模式（用户文件），0=宽松模式（includes 文件）
    
注册结构体类型，返回 StructEntry 指针

    用类型指针去重（is 比较），不用类名去重。
    这样跨模块同名类可以共存，各自有独立的字段定义。
    sha1 参数在注册时直接设置 ModuleSha1（避免 set_struct_sha1 找错 entry）。
    
向结构体添加字段，返回字段索引（-1 失败）

    default_val: 字段默认值 AST 节点（可选，None=无默认值）
    annot_class_name: 原始类型注解的类名（可选，用于联合类型字段的方法调用解析）
    
按类名 + SHA1 查找结构体，返回 StructEntry 或 None

    SHA1 非 None 时：精确匹配 name+sha1，未找到返回 None（不回退，避免跨模块同名找错）
    SHA1 为 None 时：回退到 find_struct(name) 按类名查找第一个
    
按结构体类型和字段名查找字段信息

    两遍查找策略（跨模块同名类冲突的根本修复）:
    第一遍: 类型指针 is 身份比较（最高优先级，类型唯一确定 entry）
    第二遍: 名称回退（is 未匹配时，按类名/strstr 匹配，字段未找到时 continue）
    
查找 from-import 名称，返回模块名或 None

    支持 star import: 如果 from_imports 中有 "*:module" 条目，
    且未找到精确名称匹配，且 allow_star_fallback != 0，则返回 star import 的模块名。
    
注册一个 TypeInfo。ti.Name 字段必须已设置。

        Returns:
            1 表示成功，0 表示失败（ti 为 None 或 Name 为 None）
        
按名称查找 TypeInfo。

        Returns:
            找到返回 TypeInfo*，找不到返回 None
        
初始化 lib 包的全局 _mbuddy 指针，并级联注入到所有子模块。

    Args:
        mb: memhub.MemManager 实例指针（MemBuddy 等子类通过多态传入）

    Returns:
    
将 val 强制转换为 target_ty

    整数: sext（扩展）/ trunc（截断）
    浮点: fpext（扩展）/ fptrunc（截断）
    int→float: sitofp
    float→int: fptosi
    
后缀匹配查找模块 SHA1，如 mod_suffix="__types" 匹配 "llvmlite.__types"

    用于 from .X import Y 的相对导入：impf.module 是 ".X"（带前导点），
    去掉前导点后为 "X"，SHA1 映射表中键是 "pkg.X"，需要后缀匹配。
    
从 from_imports 查找类所属模块的 SHA1，返回 None=未找到

    allow_star_fallback: 传 0 禁用 star import 回退（用于明确模块名/函数名查找）
    
在模块的函数链表中按名称查找函数

    查找策略：
    1. 精确匹配（如 "strlen" 匹配 @strlen，有 t.CExport 的函数）
    2. 后缀匹配（如 "atoi" 匹配 @"83210a72e829a086.atoi"，无 t.CExport 的函数）

    使用 llvmlite.function_get_name/next 访问器绕过 stub 类型限制
    （stub 类型字段不足且字段类型可能错误，直接字段访问会被静默跳过）。
    
获取外部函数第 param_idx 个参数的期望类型，None 表示用字面量原类型

    对 Win32 API 函数的所有非指针参数返回 i64，匹配 declare 中
    ULONG/SIZE_T 被统一翻译为 i64 的情况。
    
将 memcpy 调用映射到 @llvm.memcpy 内联函数

    直接接收三个 Value 参数，避免通过 Next 链表遍历（共享 alloca 对象的
    Next 字段可能被其他操作污染，导致链表断裂）。
    
从模板中提取前两个 %__OP 标记的编号

    结果写入 out_nums[0] 和 out_nums[1]
    返回 1 成功, 0 失败
    
结构体构造函数：按字段顺序 store 参数值，返回结构体值

    OOP 结构体：alloca → call __before_init__(ptr) → call __init__(ptr, args) 或 store 参数 → load
    普通结构体：alloca → zero + defaults → store 参数 → load
    
带关键字参数的函数调用，按参数顺序构建调用链表

    使用 llvmlite 访问器函数绕过 stub 类型限制：
    found_func.Params/RetTy/Name 和 cur_param.Name/Ty/Next 在 stub
    类型中字段不足，直接访问会被 TransPyC 静默跳过。
    
从 Subscript.slice 提取类型实参名列表

    list[int] -> ["int"]
    dict[str, int] -> ["str", "int"]
    list[AST | t.CPtr] -> ["AST|t.CPtr"]
    
注册函数到全局表（已存在则跳过），返回 0 成功

    直接操作全局表，不调用 add_func_to_table，避免递归。
    
读取 _sha1_map.txt，将 includes/ 开头的 SHA1 写入 sha1_set
    sha1_set 大小为 MAX_INCLUDES_SHA1 * 17（每个 SHA1 16字符+null）
    返回找到的 includes SHA1 数量，-1 表示错误

将 includes 扫描结果写入 _sha1_map.txt（供 StubMerger 使用）

    若 filter_set 不为 None 且 filter_count > 0，只写入 filter_set 中的条目。
    
在 out_buf 中搜索 type_name_prefix 对应的 opaque 声明行，将行首改为 ';'

    type_name_prefix 格式: '%"sha1.ClassName"'（不含 '=' 和后续内容）
    返回 1=已注释, 0=未找到
    
将文件路径转换为模块名

    特殊处理 __init__.py：includes/ast/__init__.py → ast（而非 ast.__init__）
    
递归解析AST节点，确保获取t.ASM_DESCR的实际值，支持|组合
        处理场景：
        1. t.ASM_DESCR.XXX → 取属性值
        2. t.ASM_DESCR.XXX | t.ASM_DESCR.YYY → 拼接两个值
        3. 常量字符串 → 直接返回
        
解析f-string或常量模板字符串，返回(asm_code, output_ops, input_ops, operand_seq)

多返回值装饰器
    
    用于实现函数多返回值，通过匿名结构体返回实现。
    例如：@c.CReturn(t.CInt, t.CInt) 表示函数返回两个 int 值。
    等价于 -> tuple[t.CInt, t.CInt] 返回类型注解。
    
    规则：
    1. CReturn 中有几个类型就说明要返回几个值
    2. 函数返回类型为匿名结构体 { type1, type2, ... }
    3. return 语句使用 insert_value 构建结构体
    4. 调用处使用 extract_value 提取各字段
    
内联 LLVM IR
    
    用法: c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    或:   c.LLVMIR(f"%{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    
    c.LInp(expr) - 输入操作数，翻译后替换为对应的 LLVM 临时变量名
    c.LOut(expr) - 输出操作数，翻译后替换为对应的 LLVM 临时变量名
    
LLVM IR 输入操作数标记
    
    用法: c.LInp(expr) - 标记 expr 为输入操作数
    在 c.LLVMIR 的 f-string 中使用，翻译后替换为 %N 形式的操作数引用
    
LLVM IR 输出操作数标记
    
    用法: c.LOut(expr) - 标记 expr 为输出操作数
    
#pragma 指令
    
    用于生成 C 语言的 #pragma 指令。
    例如：c.CPragma("GCC diagnostic push") 生成 #pragma GCC diagnostic push
    
生成特化类名: list + [int] -> list[int]

    分配新缓冲区拼接，避免原地 strcat 导致缓冲区溢出
    
拷贝类型注解表达式，替换类型参数 T 为具体类型名

    tp_names: 类型参数名列表 ['T']
    type_args: 类型实参名列表 ['int']
    
拷贝 ClassDef 节点用于泛型特化

    - 替换类名为 spec_name
    - 清除 type_params（特化后不是泛型类）
    - 拷贝 children 中的 AnnAssign 和 FunctionDef，替换类型注解中的 T
    - 方法体直接引用原始节点（通过 type_map 上下文处理 T）
    
特化泛型类，返回特化类名

    1. 查找泛型模板
    2. 生成特化名
    3. 检查缓存
    4. 拷贝 ClassDef 节点（替换类型注解中的 T）
    5. 设置 type_map 上下文（用于方法体中的 T 替换）
    6. 调用 translate_class_def 翻译特化类
    7. 返回特化名
    
翻译文件，返回 Translator 对象（调用者负责 dump_ir），None 失败

    current_package: 当前文件所属包名（用于解析相对导入），None 表示顶级模块
    
递归创建目录（类似 mkdir -p），目录已存在视为成功

    Args:
        path: 目录路径（支持 / 或 \ 分隔符）

    Returns:
        0 成功（包括目录已存在），非 0 失败
    
将 IR 缓冲区写入 .ll 文件

    Args:
        ir_buf: IR 文本缓冲区
        ir_len: IR 文本长度
        output_dir: 输出目录（temp 或 output）
        module_name: 模块名（如 "main"）

    Returns:
        0 成功，非 0 失败
    
调用 llc 将 .ll 编译为 .obj

    Args:
        ir_path: .ll 文件路径
        output_dir: 输出目录
        module_name: 模块名（用于生成 .obj 文件名）
        cc_cmd: 编译器命令（如 "llc"）
        cc_flags: 编译器参数（如 "-filetype=obj -relocation-model=pic"）

    Returns:
        0 成功，非 0 失败
    
扫描 includes_binary_dir 目录，收集所有 .obj 文件路径到 out_buf

    Args:
        includes_binary_dir: includes.binary 目录路径
        out_buf: 输出缓冲区（用于存放空格分隔的 .obj 文件路径）
        out_size: 输出缓冲区大小

    Returns:
        写入的字节数（不含 null 终止符），0 表示无文件或错误
    
调用 clang++ 链接 .obj 为 .exe

    Args:
        output_dir: 输出目录（包含 .obj 文件）
        module_name: 模块名
        linker_cmd: 链接器命令（如 "clang++"）
        linker_flags: 链接器参数
        linker_output: 输出文件名（如 "test.exe"）
        includes_binary_dir: includes.binary 目录路径（链接时附加预编译 .obj）

    Returns:
        0 成功，非 0 失败
    
编译 IR 到 .obj（不链接）

    Args:
        ir_buf: LLVM IR 文本缓冲区
        temp_dir: 临时目录
        module_name: 模块名（SHA1）
        cc_cmd: 编译器命令
        cc_flags: 编译器参数

    Returns:
        0 成功，非 0 失败
    
链接多个 .obj 文件为 .exe

    Args:
        obj_paths: 空格分隔的 .obj 文件完整路径字符串
        obj_paths_len: obj_paths 长度
        linker_output: 输出文件完整路径

    Returns:
        0 成功，非 0 失败
    
执行完整编译管线

    Args:
        linker_cmd: 链接器命令
        linker_output: 输出文件名

    Returns:
        BuildResult 对象