# 类型定义模块 import re import types from typing import TypeVar, Generic, TypeAlias # ============================================================================= # 类型映射常量 # ============================================================================= # 类型映射常量(由 _build_type_maps() 在模块末尾自动生成) _BASIC_TYPES_MAP = {} _T_TYPE_PATTERNS = [] def _build_type_maps(): global _BASIC_TYPES_MAP, _T_TYPE_PATTERNS for _name in dir(): _obj = eval(_name) if isinstance(_obj, type) and issubclass(_obj, CType) and _obj is not CType: try: _inst = _obj() _cname = getattr(_inst, 'CName', '') if _cname and _obj.IsBasicType(): _BASIC_TYPES_MAP[_cname] = _cname _T_TYPE_PATTERNS.append((_name, _cname)) except Exception: pass # ============================================================================= # CType 基类 # ============================================================================= class CType: """C 类型基类""" PREFIX = 'prefix' BASE = 'base' POINTER = 'ptr' ARRAY = 'array' NAMED = 'named' STORAGE_CLASS = 'storage_class' TYPE_QUALIFIER = 'type_qualifier' position = frozenset({BASE}) # 类属性,支持联合类型如 BASE | SPECIAL def __init__(self, value=None, *types): self.value = value self.types = types self.Name = '' self.IsBasicType = False self.IsPointer = False self.IsSigned = None self.Size = None if not hasattr(self, 'CName'): self.CName = '' def GetPositions(self) -> frozenset: """获取 position 的 frozenset 形式""" return self.position @classmethod def HasPosition(cls, pos) -> bool: """检查是否包含指定的位置""" return pos in cls.position @classmethod def IsNamed(cls) -> bool: """检查是否是命名类型(struct/union/enum/typedef 等)""" return cls.NAMED in cls.position @classmethod def IsStorageClass(cls) -> bool: """检查是否是存储类修饰符""" return cls.STORAGE_CLASS in cls.position @classmethod def IsTypeQualifier(cls) -> bool: """检查是否是类型限定符""" return cls.TYPE_QUALIFIER in cls.position @classmethod def IsBasicType(cls) -> bool: """检查是否是基本类型""" return cls.BASE in cls.position @classmethod def IsPrefix(cls) -> bool: """检查是否是前缀类型""" return cls.PREFIX in cls.position def rfind(self, s): """注解""" pass def get_position(self): """获取类型在声明中的位置""" return self.position def GetCAame(self): """获取 C 类型名称""" return self.CName def __merge__(self, types): return types def __or__(self, other): return [self, other] def __set_default__(self, **kwargs): """设置默认值/初始值,用于 static/global 变量的初始化 Args: **kwargs: 成员名称和值的键值对 Returns: 包含默认值信息的 CTypeDefault 对象 """ return CTypeDefault(self, **kwargs) @classmethod def FromAnnotation(cls, AnnotationStr, TypeName=''): """从类型注解字符串解析类型信息 Args: AnnotationStr: 类型注解的字符串表示(ast.dump结果) TypeName: 类型名称(可选) Returns: CType 实例 """ ctype = cls() # 检查是否是基本类型 if TypeName in _BASIC_TYPES_MAP: ctype.IsBasicType = True ctype.Name = _BASIC_TYPES_MAP[TypeName] else: for pattern, c_name in _T_TYPE_PATTERNS: if pattern in AnnotationStr: ctype.IsBasicType = True ctype.Name = c_name break # 检查是否包含指针 if 'CPtr' in AnnotationStr: ctype.IsPointer = True return ctype @classmethod def FromTypeName(cls, TypeName): """从类型名称创建 CType Args: TypeName: 类型名称 Returns: CType 实例 """ ctype = cls() if TypeName in _BASIC_TYPES_MAP: ctype.IsBasicType = True ctype.Name = _BASIC_TYPES_MAP[TypeName] return ctype def GetFullType(self, VarName='', ArraySizeStr=''): """获取完整的类型声明字符串 Args: VarName: 变量名 ArraySizeStr: 数组大小字符串 Returns: 完整的类型声明字符串 """ ptr_str = '*' if self.IsPointer else '' if VarName: return f'{self.Name}{ptr_str} {VarName}{ArraySizeStr}' return f'{self.Name}{ptr_str}' def __repr__(self): ptr_str = '*' if self.IsPointer else '' return f'CType({self.Name}{ptr_str}, IsBasicType={self.IsBasicType})' class CChar(CType): def __init__(self, value=None): self.CName = 'char' super().__init__(value) self.IsSigned = True self.Size = 8 class CInt(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'int' super().__init__(value) self.IsSigned = True self.Size = 32 class CShort(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'short' super().__init__(value) self.IsSigned = True self.Size = 16 class CLong(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'long' super().__init__(value) self.IsSigned = True self.Size = 64 class CFloat(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'float' super().__init__(value) self.IsSigned = None self.Size = 32 class CDouble(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'double' super().__init__(value) self.IsSigned = None self.Size = 64 class CFloat8T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'float8_t' super().__init__(value) self.IsSigned = None self.Size = 8 class CFloat16T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'float16_t' super().__init__(value) self.IsSigned = None self.Size = 16 class CFloat32T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'float32_t' super().__init__(value) self.IsSigned = None self.Size = 32 class CFloat64T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'float64_t' super().__init__(value) self.IsSigned = None self.Size = 64 class CFloat128T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'float128_t' super().__init__(value) self.IsSigned = None self.Size = 128 class CVoid(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'void' super().__init__(value) self.IsSigned = None self.Size = 0 class CUnsigned(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'unsigned' super().__init__(value) self.IsSigned = False self.Size = 32 class CUnsignedChar(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'unsigned char' super().__init__(value) self.IsSigned = False self.Size = 8 class CUnsignedInt(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'unsigned int' super().__init__(value) self.IsSigned = False self.Size = 32 class CUnsignedShort(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'unsigned short' super().__init__(value) self.IsSigned = False self.Size = 16 class CUnsignedLong(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'unsigned long' super().__init__(value) self.IsSigned = False self.Size = 64 class CSignedChar(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'signed char' super().__init__(value) self.IsSigned = True self.Size = 8 class CStruct(CType): position = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value=None, name=None): self.CName = f'struct {name}' if name else 'struct' super().__init__(value) class CUnion(CType): position = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value=None): self.CName = 'union' super().__init__(value) class CEnum(CType): position = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value=None): self.CName = 'enum' super().__init__(value) self.b = 1 Enum = CEnum # 别名,允许使用 t.Enum ''' class Object(CType): """Python 对象类型,用于支持类方法外联函数""" position = frozenset({CType.BASE, CType.NAMED}) def __init__(self, value=None): self.CName = 'struct' super().__init__(value) def __call__(self, cls): return cls ''' def Object(): pass def CVTable(): pass CTypedef = TypeAlias class _CTypedef(CType): position = frozenset({CType.PREFIX, CType.NAMED}) def __init__(self, value=None): self.CName = 'typedef' super().__init__(value) class CAuto(CType): position = frozenset({CType.PREFIX}) def __init__(self, value=None): self.CName = 'auto' super().__init__(value) class CRegister(CType): position = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value=None): self.CName = 'register' super().__init__(value) class CStatic(CType): position = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value=None): self.CName = 'static' super().__init__(value) class CExtern(CType): position = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value=None): self.CName = 'extern' super().__init__(value) class CConst(CType): position = frozenset({CType.PREFIX, CType.TYPE_QUALIFIER}) def __init__(self, value=None): self.CName = 'const' super().__init__(value) class CInline(CType): position = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value=None): self.CName = 'inline' super().__init__(value) class CExport(CType): position = frozenset({CType.PREFIX, CType.STORAGE_CLASS}) def __init__(self, value=None): self.CName = 'export' super().__init__(value) class CVolatile(CType): position = frozenset({CType.PREFIX, CType.TYPE_QUALIFIER}) def __init__(self, value=None): self.CName = 'volatile' super().__init__(value) class CSizeT(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'size_t' super().__init__(value) self.IsSigned = False self.Size = 64 class CInt8T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'int8_t' super().__init__(value) self.IsSigned = True self.Size = 8 class CInt16T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'int16_t' super().__init__(value) self.IsSigned = True self.Size = 16 class CInt32T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'int32_t' super().__init__(value) self.IsSigned = True self.Size = 32 class CInt64T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'int64_t' super().__init__(value) self.IsSigned = True self.Size = 64 class CUInt8T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'uint8_t' super().__init__(value) self.IsSigned = False self.Size = 8 class CUInt16T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'uint16_t' super().__init__(value) self.IsSigned = False self.Size = 16 class CUInt32T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'uint32_t' super().__init__(value) self.IsSigned = False self.Size = 32 class CUInt64T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'uint64_t' super().__init__(value) self.IsSigned = False self.Size = 64 class CIntPtrT(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'intptr_t' super().__init__(value) self.IsSigned = True self.Size = 64 class CUIntPtrT(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'uintptr_t' super().__init__(value) self.IsSigned = False self.Size = 64 class CPtrDiffT(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'ptrdiff_t' super().__init__(value) self.IsSigned = True self.Size = 64 class CWCharT(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'wchar_t' super().__init__(value) self.IsSigned = True self.Size = 32 class CChar8T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'char8_t' super().__init__(value) self.IsSigned = False self.Size = 8 class CChar16T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'char16_t' super().__init__(value) self.IsSigned = False self.Size = 16 class CChar32T(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'char32_t' super().__init__(value) self.IsSigned = False self.Size = 32 class CBool(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = 'bool' super().__init__(value) self.IsSigned = False self.Size = 8 class CComplex(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = '_Complex' super().__init__(value) class CImaginary(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = '_Imaginary' super().__init__(value) T = TypeVar("T") Callable = Generic[T] class CPtr(CType, Generic[T]): position = frozenset({CType.POINTER}) def __init__(self, value=None): self.CName = '*' super().__init__(value) class CTypeDefault(CType): """用于存储 C 类型默认值/初始化的包装类 当使用 t.CStatic.__set_default__(open=mouse_open, ...) 时创建 """ def __init__(self, BaseType, **kwargs): super().__init__() self.BaseType = BaseType self.defaults = kwargs self.CName = BaseType.CName if hasattr(BaseType, 'CName') else '' self.position = BaseType.position if hasattr(BaseType, 'position') else CType.BASE def __repr__(self): return f'CTypeDefault({self.BaseType}, {self.defaults})' class CArrayPtr(CType): position = frozenset({CType.POINTER}) def __init__(self, value=None): self.CName = '(*)' # 特殊标记表示数组指针 super().__init__(value) class CDefine(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = '#define' super().__init__(value) class CPass(CType): position = frozenset({CType.BASE}) def __init__(self, value=None): self.CName = '' super().__init__(value) class State(CType): """状态标记,用于仅声明不定义,等价于 CExport | CExtern""" position = frozenset({CType.PREFIX}) @staticmethod def HandleCall(translator, args, keywords): """处理 t.State() 调用""" return ['t.State'] class Anonymous: def __init__(): pass class Postdefinition: def __init__(self, c): pass class Bit: def __init__(self, i): pass class BigEndian(CType): """大端序(Big-Endian)字节序标记类 用于标记结构体成员应使用大端序存储。 在小端序平台(如x86)上读取时,会自动进行字节交换。 用法示例: class MyStruct: a: t.CInt | t.BigEndian # 大端序存储的整数 """ IsSigned = True Size = 4 Align = 4 class LittleEndian(CType): """小端序(Little-Endian)字节序标记类 用于标记结构体成员应使用小端序存储。 在小端序平台(如x86)上读取时,不需要进行字节交换。 用法示例: class MyStruct: b: t.CInt | t.LittleEndian # 小端序存储的整数 """ IsSigned = True Size = 4 Align = 4 class ASM_DESCR: """内嵌 ASM 破坏描述符类 定义了所有可能的破坏描述符和约束字符,用于 GCC 内嵌汇编 """ # 操作数修饰符 MODIFIER_OUTPUT = '=' # 输出操作数 MODIFIER_READWRITE = '+' # 读写操作数 MODIFIER_INPUT = '' # 输入操作数(默认) MODIFIER_GLOBAL = '&' # 全局操作数 # 寄存器约束(32位命名) REG_ANY = 'r' # 任何通用寄存器 REG_EAX = 'a' # EAX/RAX 寄存器 REG_EBX = 'b' # EBX/RBX 寄存器 REG_ECX = 'c' # ECX/RCX 寄存器 REG_EDX = 'd' # EDX/RDX 寄存器 REG_ESI = 'S' # ESI/RSI 寄存器 REG_EDI = 'D' # EDI/RDI 寄存器 REG_STACK = 'q' # 任何通用寄存器(EAX, EBX, ECX, EDX) REG_FLOAT = 'f' # 浮点寄存器 REG_MMX = 'y' # MMX 寄存器 REG_XMM = 'x' # XMM 寄存器 # 寄存器约束(64位命名,GCC约束字符与32位相同) REG_RAX = 'a' # RAX 寄存器 REG_RBX = 'b' # RBX 寄存器 REG_RCX = 'c' # RCX 寄存器 REG_RDX = 'd' # RDX 寄存器 REG_RSI = 'S' # RSI 寄存器 REG_RDI = 'D' # RDI 寄存器 REG_R8 = 'r' # R8 寄存器(需通过r约束+显式指定) REG_R9 = 'r' # R9 寄存器 REG_R10 = 'r' # R10 寄存器 REG_R11 = 'r' # R11 寄存器 REG_R12 = 'r' # R12 寄存器 REG_R13 = 'r' # R13 寄存器 REG_R14 = 'r' # R14 寄存器 REG_R15 = 'r' # R15 寄存器 REG_RBP = 'r' # RBP 寄存器 REG_RSP = 'r' # RSP 寄存器 # 内存约束 MEMORY = 'm' # 内存操作数 # 立即数约束 IMMEDIATE = 'i' # 立即数 IMMEDIATE_CONST = 'n' # 常量立即数 # 综合约束 ANY = 'g' # 任何通用寄存器、内存或立即数 MEMORY_OR_REG = 'o' # 内存或寄存器 # 破坏描述符(clobber list) CLOBBER_EAX = 'eax' # 破坏 EAX/RAX 寄存器 CLOBBER_EBX = 'ebx' # 破坏 EBX/RBX 寄存器 CLOBBER_ECX = 'ecx' # 破坏 ECX/RCX 寄存器 CLOBBER_EDX = 'edx' # 破坏 EDX/RDX 寄存器 CLOBBER_ESI = 'esi' # 破坏 ESI/RSI 寄存器 CLOBBER_EDI = 'edi' # 破坏 EDI/RDI 寄存器 CLOBBER_EBP = 'ebp' # 破坏 EBP/RBP 寄存器 CLOBBER_ESP = 'esp' # 破坏 ESP/RSP 寄存器 CLOBBER_AL = 'al' # 破坏 AL 寄存器(EAX/RAX 低8位) CLOBBER_AH = 'ah' # 破坏 AH 寄存器(EAX/RAX 高8位) CLOBBER_BL = 'bl' # 破坏 BL 寄存器(EBX/RBX 低8位) CLOBBER_BH = 'bh' # 破坏 BH 寄存器(EBX/RBX 高8位) CLOBBER_CL = 'cl' # 破坏 CL 寄存器(ECX/RCX 低8位) CLOBBER_CH = 'ch' # 破坏 CH 寄存器(ECX/RCX 高8位) CLOBBER_DL = 'dl' # 破坏 DL 寄存器(EDX/RDX 低8位) CLOBBER_DH = 'dh' # 破坏 DH 寄存器(EDX/RDX 高8位) CLOBBER_CC = 'cc' # 破坏条件代码寄存器(标志寄存器) CLOBBER_MEMORY = 'memory' # 破坏内存(表示汇编代码修改了内存) # 16 位寄存器破坏描述符 CLOBBER_AX = 'ax' # 破坏 AX 寄存器 CLOBBER_BX = 'bx' # 破坏 BX 寄存器 CLOBBER_CX = 'cx' # 破坏 CX 寄存器 CLOBBER_DX = 'dx' # 破坏 DX 寄存器 CLOBBER_SI = 'si' # 破坏 SI 寄存器 CLOBBER_DI = 'di' # 破坏 DI 寄存器 CLOBBER_BP = 'bp' # 破坏 BP 寄存器 # 64位寄存器破坏描述符 CLOBBER_RAX = 'rax' # 破坏 RAX 寄存器 CLOBBER_RBX = 'rbx' # 破坏 RBX 寄存器 CLOBBER_RCX = 'rcx' # 破坏 RCX 寄存器 CLOBBER_RDX = 'rdx' # 破坏 RDX 寄存器 CLOBBER_RSI = 'rsi' # 破坏 RSI 寄存器 CLOBBER_RDI = 'rdi' # 破坏 RDI 寄存器 CLOBBER_RBP = 'rbp' # 破坏 RBP 寄存器 CLOBBER_RSP = 'rsp' # 破坏 RSP 寄存器 CLOBBER_R8 = 'r8' # 破坏 R8 寄存器 CLOBBER_R9 = 'r9' # 破坏 R9 寄存器 CLOBBER_R10 = 'r10' # 破坏 R10 寄存器 CLOBBER_R11 = 'r11' # 破坏 R11 寄存器 CLOBBER_R12 = 'r12' # 破坏 R12 寄存器 CLOBBER_R13 = 'r13' # 破坏 R13 寄存器 CLOBBER_R14 = 'r14' # 破坏 R14 寄存器 CLOBBER_R15 = 'r15' # 破坏 R15 寄存器 # 预定义的组合约束(32位命名) OUTPUT_REG = '=r' # 输出操作数,使用任何通用寄存器 OUTPUT_MEM = '=m' # 输出操作数,使用内存 OUTPUT_EAX = '=a' # 输出操作数,使用 EAX/RAX 寄存器 OUTPUT_EBX = '=b' # 输出操作数,使用 EBX/RBX 寄存器 OUTPUT_ECX = '=c' # 输出操作数,使用 ECX/RCX 寄存器 OUTPUT_EDX = '=d' # 输出操作数,使用 EDX/RDX 寄存器 OUTPUT_ESI = '=S' # 输出操作数,使用 ESI/RSI 寄存器 OUTPUT_EDI = '=D' # 输出操作数,使用 EDI/RDI 寄存器 # 预定义的组合约束(64位命名) OUTPUT_RAX = '=a' # 输出操作数,使用 RAX 寄存器 OUTPUT_RBX = '=b' # 输出操作数,使用 RBX 寄存器 OUTPUT_RCX = '=c' # 输出操作数,使用 RCX 寄存器 OUTPUT_RDX = '=d' # 输出操作数,使用 RDX 寄存器 OUTPUT_RSI = '=S' # 输出操作数,使用 RSI 寄存器 OUTPUT_RDI = '=D' # 输出操作数,使用 RDI 寄存器 INPUT_REG = 'r' # 输入操作数,使用任何通用寄存器 INPUT_MEM = 'm' # 输入操作数,使用内存 INPUT_EAX = 'a' # 输入操作数,使用 EAX/RAX 寄存器 INPUT_EBX = 'b' # 输入操作数,使用 EBX/RBX 寄存器 INPUT_ECX = 'c' # 输入操作数,使用 ECX/RCX 寄存器 INPUT_EDX = 'd' # 输入操作数,使用 EDX/RDX 寄存器 INPUT_ESI = 'S' # 输入操作数,使用 ESI/RSI 寄存器 INPUT_EDI = 'D' # 输入操作数,使用 EDI/RDI 寄存器 INPUT_IMM = 'i' # 输入操作数,使用立即数 INPUT_ANY = 'g' # 输入操作数,使用任何通用寄存器、内存或立即数 # 输入约束(64位命名) INPUT_RAX = 'a' # 输入操作数,使用 RAX 寄存器 INPUT_RBX = 'b' # 输入操作数,使用 RBX 寄存器 INPUT_RCX = 'c' # 输入操作数,使用 RCX 寄存器 INPUT_RDX = 'd' # 输入操作数,使用 RDX 寄存器 INPUT_RSI = 'S' # 输入操作数,使用 RSI 寄存器 INPUT_RDI = 'D' # 输入操作数,使用 RDI 寄存器 # 所有单独约束字符列表 ALL_CONSTRAINTS = [ # 操作数修饰符 MODIFIER_OUTPUT, MODIFIER_READWRITE, MODIFIER_INPUT, MODIFIER_GLOBAL, # 寄存器约束 REG_ANY, REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_ESI, REG_EDI, REG_STACK, REG_FLOAT, REG_MMX, REG_XMM, # 内存约束 MEMORY, # 立即数约束 IMMEDIATE, IMMEDIATE_CONST, # 综合约束 ANY, MEMORY_OR_REG ] # 所有破坏描述符列表 ALL_CLOBBERS = [ CLOBBER_EAX, CLOBBER_EBX, CLOBBER_ECX, CLOBBER_EDX, CLOBBER_ESI, CLOBBER_EDI, CLOBBER_EBP, CLOBBER_ESP, CLOBBER_CC, CLOBBER_MEMORY, CLOBBER_RAX, CLOBBER_RBX, CLOBBER_RCX, CLOBBER_RDX, CLOBBER_RSI, CLOBBER_RDI, CLOBBER_RBP, CLOBBER_RSP, CLOBBER_R8, CLOBBER_R9, CLOBBER_R10, CLOBBER_R11, CLOBBER_R12, CLOBBER_R13, CLOBBER_R14, CLOBBER_R15 ] # 所有描述符列表 ALL = ALL_CONSTRAINTS + ALL_CLOBBERS # 定义 ASM_LIST,包含所有可能的汇编约束字符 ASM_LIST = ASM_DESCR.ALL class attr: """C 语言 __attribute__ 属性操作类型""" @staticmethod def noreturn(): return "noreturn" @staticmethod def format(printf, arg1, arg2): return f"format({printf}, {arg1}, {arg2})" @staticmethod def section(name): return f'section("{name}")' @staticmethod def aligned(bytes): return f"aligned({bytes})" @staticmethod def packed(): return "packed" @staticmethod def unused(): return "unused" @staticmethod def used(): return "used" @staticmethod def weak(): return "weak" @staticmethod def alias(name): return f'alias("{name}")' @staticmethod def visibility(type): return f'visibility("{type}")' @staticmethod def constructor(): return "constructor" @staticmethod def destructor(): return "destructor" @staticmethod def always_inline(): return "always_inline" @staticmethod def noinline(): return "noinline" @staticmethod def pure(): return "pure" @staticmethod def const(): return "const" @staticmethod def malloc(): return "malloc" @staticmethod def alloc_size(n): return f"alloc_size({n})" @staticmethod def warn_unused_result(): return "warn_unused_result" @staticmethod def deprecated(msg=None): if msg: return f'deprecated("{msg}")' return "deprecated" @staticmethod def fallthrough(): return "fallthrough" @staticmethod def likely(): return "likely" @staticmethod def unlikely(): return "unlikely" @staticmethod def hot(): return "hot" @staticmethod def cold(): return "cold" @staticmethod def interrupt(): return "interrupt" @staticmethod def naked(): return "naked" @staticmethod def sentinel(n=0): return f"sentinel({n})" @staticmethod def nonnull(*args): if args: return f"nonnull({', '.join(map(str, args))})" return "nonnull" @staticmethod def returns_nonnull(): return "returns_nonnull" @staticmethod def access(mode, *args): return f"access({mode}, {', '.join(map(str, args))})" @staticmethod def cleanup(func): return f'cleanup({func})' @staticmethod def transparent_union(): return "transparent_union" @staticmethod def mode(mode_name): return f"mode({mode_name})" @staticmethod def vector_size(bytes): return f"vector_size({bytes})" @staticmethod def target(string): return f'target("{string}")' @staticmethod def optimize(level): return f'optimize("{level}")' @staticmethod def no_instrument_function(): return "no_instrument_function" @staticmethod def no_sanitize(type): return f"no_sanitize({type})" @staticmethod def no_stack_protector(): return "no_stack_protector" @staticmethod def stack_protector(): return "stack_protector" @staticmethod def error(msg): return f'error("{msg}")' @staticmethod def warning(msg): return f'warning("{msg}")' class llvm: """LLVM 函数属性描述符 用于在返回类型注解中指定 LLVM 函数属性。 例如: def foo() -> t.CInt | t.attr.llvm.nobuiltin | t.attr.llvm.nounwind: """ class nobuiltin: CName = '#attr.llvm.nobuiltin' class nounwind: CName = '#attr.llvm.nounwind' class noredzone: CName = '#attr.llvm.noredzone' class willreturn: CName = '#attr.llvm.willreturn' class mustprogress: CName = '#attr.llvm.mustprogress' class optnone: CName = '#attr.llvm.optnone' class noinline: CName = '#attr.llvm.noinline' class alwaysinline: CName = '#attr.llvm.alwaysinline' class readnone: CName = '#attr.llvm.readnone' class readonly: CName = '#attr.llvm.readonly' class writeonly: CName = '#attr.llvm.writeonly' class inaccessiblememonly: CName = '#attr.llvm.inaccessiblememonly' class inaccessiblemem_or_argmemonly: CName = '#attr.llvm.inaccessiblemem_or_argmemonly' def NewCType(size, signed): ct = CType() ct.Size = size ct.IsSigned = signed return ct i1 = NewCType(1, True) i8 = NewCType(8, True) i16 = NewCType(16, True) i32 = NewCType(32, True) i64 = NewCType(64, True) u1 = NewCType(1, False) u8 = NewCType(8, False) u16 = NewCType(16, False) u32 = NewCType(32, False) u64 = NewCType(64, False) class CTypeRegistry: """基于 CType 元属性的类型注册表,替代手动映射表 利用 CType 子类的 position/IsSigned/Size 元属性自动推导: - LLVM IR 类型字符串 (如 'i32', 'double', 'i8*') - C 类型名称 (如 'int', 'unsigned char', 'long long') - Python CType 类引用 (如 t.CInt32T) """ _name_to_class = None _cname_to_class = None @classmethod def _build(cls): if cls._name_to_class is not None: return import sys mod = sys.modules.get(__name__) if mod is None: return cls._name_to_class = {} cls._cname_to_class = {} for name, obj in vars(mod).items(): if not isinstance(obj, type) or not issubclass(obj, CType) or obj is CType: continue if obj in (CTypeDefault, BigEndian, LittleEndian): continue try: inst = obj() except Exception: continue pos = getattr(obj, 'position', frozenset()) if CType.PREFIX in pos and CType.BASE not in pos: continue if CType.POINTER in pos and CType.BASE not in pos: cls._name_to_class[name] = obj continue if getattr(inst, 'Size', None) is not None or getattr(inst, 'CName', ''): cls._name_to_class[name] = obj cname = getattr(inst, 'CName', '') if cname and cname not in cls._cname_to_class: cls._cname_to_class[cname] = obj @classmethod def GetClassByName(cls, name: str): """根据 Python 类名获取 CType 类 (如 'CInt32T' -> t.CInt32T)""" cls._build() return cls._name_to_class.get(name) @classmethod def GetClassByCName(cls, cname: str): """根据 C 类型名获取 CType 类 (如 'int32_t' -> t.CInt32T)""" cls._build() return cls._cname_to_class.get(cname) @staticmethod def CTypeToLLVM(ctype_class) -> str: """从 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} """ if ctype_class is None: return 'i8*' pos = getattr(ctype_class, 'position', frozenset()) if CType.POINTER in pos and CType.BASE not in pos: return 'i8*' if CType.PREFIX in pos and CType.BASE not in pos: return '' try: inst = ctype_class() except Exception: return 'i8*' size = getattr(inst, 'Size', None) is_signed = getattr(inst, 'IsSigned', None) if size is None or size == 0: if is_signed is None: return 'void' return 'i8*' if is_signed is None: float_map = {8: 'half', 16: 'half', 32: 'float', 64: 'double', 128: 'fp128'} return float_map.get(size, f'f{size}') return f'i{size}' @staticmethod def CTypeToCName(ctype_class) -> str: """从 CType 类推导 C 类型名称 (用于 printf 格式化等) 规则: - IsSigned is None 且 Size > 0 → 浮点: float/double/long double - IsSigned is True → 有符号整数: char/short/int/long long - IsSigned is False → 无符号整数: unsigned char/unsigned short/unsigned int/unsigned long long """ if ctype_class is None: return '' try: inst = ctype_class() except Exception: return '' size = getattr(inst, 'Size', None) is_signed = getattr(inst, 'IsSigned', None) if size is None: return '' if is_signed is None and size > 0: float_cname = {32: 'float', 64: 'double', 128: 'long double'} return float_cname.get(size, 'double') int_cname_signed = {8: 'char', 16: 'short', 32: 'int', 64: 'long long'} int_cname_unsigned = {8: 'unsigned char', 16: 'unsigned short', 32: 'unsigned int', 64: 'unsigned long long'} if is_signed: return int_cname_signed.get(size, 'int') else: return int_cname_unsigned.get(size, 'unsigned int') @classmethod def NameToLLVM(cls, name: str) -> str: """根据 Python 类型名推导 LLVM IR 类型 (如 'CFloat64T' -> 'double') 修饰符类型 (CConst, CStatic 等) 返回空字符串。 指针类型 (CPtr) 返回 'i8*'。 未知类型返回 None。 """ cls._build() import sys mod = sys.modules.get(__name__) if mod and hasattr(mod, name): obj = getattr(mod, name) if isinstance(obj, type) and issubclass(obj, CType): return cls.CTypeToLLVM(obj) return None @classmethod def NameToCName(cls, name: str) -> str: """根据 Python 类型名推导 C 类型名 (如 'CInt32T' -> 'int')""" ctype_class = cls.GetClassByName(name) if ctype_class is not None: return cls.CTypeToCName(ctype_class) return None @classmethod def CNameToClass(cls, cname: str): """根据 C 类型名获取 CType 类 (如 'int32_t' -> t.CInt32T, 'unsigned char' -> t.CUnsignedChar)""" cls._build() return cls._cname_to_class.get(cname) @classmethod def ResolveName(cls, name: str): """解析类型名到 (CType类, 指针层级) 支持的格式: - Python 类名: 'CInt32T' -> (t.CInt32T, 0) - C 类型名: 'int32_t' -> (t.CInt32T, 0) - stdint 大写别名: 'INT32' -> (t.CInt32T, 0) - 指针别名: 'INT32PTR' -> (t.CInt32T, 1) - 大写别名: 'BYTE' -> (t.CUnsignedChar, 0), 'DWORD' -> (t.CUInt32T, 0) - 浮点别名: 'FLOAT64' -> (t.CFloat64T, 0) - void指针: 'VOIDPTR' -> (t.CVoid, 1) """ cls._build() direct = cls._name_to_class.get(name) if direct is not None: pos = getattr(direct, 'position', frozenset()) ptr_level = 1 if CType.POINTER in pos and CType.BASE not in pos else 0 return (direct, ptr_level) cnameres = cls._cname_to_class.get(name) if cnameres is not None: return (cnameres, 0) if name.endswith('PTR'): base_name = name[:-3] base_result = cls.ResolveName(base_name) if base_result is not None: return (base_result[0], base_result[1] + 1) if name.startswith('FLOAT') and name[5:].isdigit(): bits = int(name[5:]) float_name = f'CFloat{bits}T' float_cls = cls._name_to_class.get(float_name) if float_cls is not None: return (float_cls, 0) _UPPER_ALIAS = { 'BYTE': 'CUInt8T', 'INT8': 'CInt8T', 'UINT8': 'CUInt8T', 'WORD': 'CUInt16T', 'INT16': 'CInt16T', 'UINT16': 'CUInt16T', 'DWORD': 'CUInt32T', 'INT32': 'CInt32T', 'UINT32': 'CUInt32T', 'UINT': 'CUnsignedInt', 'INT': 'CInt', 'QWORD': 'CUInt64T', 'INT64': 'CInt64T', 'UINT64': 'CUInt64T', 'INTPTR': 'CIntPtrT', 'UINTPTR': 'CUIntPtrT', 'SIZE_T': 'CSizeT', 'SSIZE_T': 'CPtrDiffT', 'PTRDIFF_T': 'CPtrDiffT', 'VOID': 'CVoid', } alias = _UPPER_ALIAS.get(name) if alias: alias_cls = cls._name_to_class.get(alias) if alias_cls is not None: return (alias_cls, 0) return None _build_type_maps()