1163 lines
40 KiB
Python
1163 lines
40 KiB
Python
# 类型定义模块
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
import types
|
||
from typing import Any, ClassVar, Optional, TypeVar, Generic, TypeAlias
|
||
|
||
from lib.constants.config import mode as _ConfigMode
|
||
from lib.core.VLogger import get_logger as _vlog
|
||
|
||
|
||
# =============================================================================
|
||
# 类型映射常量
|
||
# =============================================================================
|
||
|
||
# 标记基类注册表(由 @_marker_base 装饰器自动注册,或手动添加)
|
||
_MARKER_BASES: set[str] = set()
|
||
|
||
def _marker_base(cls: type) -> type:
|
||
"""将类名注册为标记基类,供 HandlesClassDef 检测使用"""
|
||
_MARKER_BASES.add(cls.__name__)
|
||
return cls
|
||
|
||
# 平台相关类型的默认 Size(可由 configure_platform 修改)
|
||
_LONG_SIZE = 64
|
||
_UNSIGNED_LONG_SIZE = 64
|
||
_WCHAR_T_SIZE = 32
|
||
_SIZE_T_SIZE = 64
|
||
_INTPTR_T_SIZE = 64
|
||
_UINTPTR_T_SIZE = 64
|
||
_PTRDIFF_T_SIZE = 64
|
||
|
||
def configure_platform(triple: Optional[str] = None) -> None:
|
||
"""根据目标三元组配置平台相关类型的大小
|
||
|
||
Args:
|
||
triple: LLVM 目标三元组字符串,如 'x86_64-pc-windows-gnu'
|
||
"""
|
||
global _LONG_SIZE, _UNSIGNED_LONG_SIZE, _WCHAR_T_SIZE
|
||
global _SIZE_T_SIZE, _INTPTR_T_SIZE, _UINTPTR_T_SIZE, _PTRDIFF_T_SIZE
|
||
if not triple:
|
||
return
|
||
triple_lower: str = triple.lower()
|
||
is_windows: bool = any(k in triple_lower for k in ('windows', 'win32', 'mingw', 'msvc', 'cygwin'))
|
||
is_32bit: bool = any(k in triple_lower for k in ('i386', 'i686'))
|
||
if is_windows:
|
||
_LONG_SIZE = 32 # Windows LLP64: long = 32 位
|
||
_UNSIGNED_LONG_SIZE = 32
|
||
_WCHAR_T_SIZE = 16 # Windows: wchar_t = 16 位
|
||
if is_32bit:
|
||
_SIZE_T_SIZE = 32
|
||
_INTPTR_T_SIZE = 32
|
||
_UINTPTR_T_SIZE = 32
|
||
_PTRDIFF_T_SIZE = 32
|
||
|
||
|
||
# =============================================================================
|
||
# CType 基类
|
||
# =============================================================================
|
||
|
||
class CType:
|
||
"""C 类型基类"""
|
||
|
||
PREFIX: ClassVar[str] = 'prefix'
|
||
BASE: ClassVar[str] = 'base'
|
||
POINTER: ClassVar[str] = 'ptr'
|
||
ARRAY: ClassVar[str] = 'array'
|
||
NAMED: ClassVar[str] = 'named'
|
||
STORAGE_CLASS: ClassVar[str] = 'storage_class'
|
||
TYPE_QUALIFIER: ClassVar[str] = 'type_qualifier'
|
||
|
||
position: ClassVar[frozenset[str]] = frozenset({BASE}) # 类属性,支持联合类型如 BASE | SPECIAL
|
||
|
||
def __init__(self, value: Any = None, *types: Any) -> None:
|
||
self.value: Any = value
|
||
self.types: tuple[Any, ...] = types
|
||
self.Name: str = ''
|
||
self.IsBasicType: bool = False
|
||
self.IsPointer: bool = False
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: Optional[int] = None
|
||
|
||
def GetPositions(self) -> frozenset[str]:
|
||
"""获取 position 的 frozenset 形式"""
|
||
return self.position
|
||
|
||
@classmethod
|
||
def HasPosition(cls, pos: str) -> 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: str) -> None:
|
||
"""注解"""
|
||
pass
|
||
|
||
def get_position(self) -> frozenset[str]:
|
||
"""获取类型在声明中的位置"""
|
||
return self.position
|
||
|
||
def __merge__(self, types: Any) -> Any:
|
||
return types
|
||
|
||
def __or__(self, other: Any) -> list[Any]:
|
||
return [self, other]
|
||
|
||
def __set_default__(self, **kwargs: Any) -> CTypeDefault:
|
||
"""设置默认值/初始值,用于 static/global 变量的初始化
|
||
|
||
Args:
|
||
**kwargs: 成员名称和值的键值对
|
||
|
||
Returns:
|
||
包含默认值信息的 CTypeDefault 对象
|
||
"""
|
||
return CTypeDefault(self, **kwargs)
|
||
|
||
def GetFullType(self, VarName: str = '', ArraySizeStr: str = '') -> str:
|
||
"""获取完整的类型声明字符串
|
||
|
||
Args:
|
||
VarName: 变量名
|
||
ArraySizeStr: 数组大小字符串
|
||
|
||
Returns:
|
||
完整的类型声明字符串
|
||
"""
|
||
ptr_str: str = '*' if self.IsPointer else ''
|
||
if VarName:
|
||
return f'{self.Name}{ptr_str} {VarName}{ArraySizeStr}'
|
||
return f'{self.Name}{ptr_str}'
|
||
|
||
def __repr__(self) -> str:
|
||
ptr_str: str = '*' if self.IsPointer else ''
|
||
return f'CType({self.Name}{ptr_str}, IsBasicType={self.IsBasicType})'
|
||
|
||
class CChar(CType):
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 8
|
||
|
||
class CInt(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 32
|
||
|
||
class CShort(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 16
|
||
|
||
class CLong(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = _LONG_SIZE
|
||
|
||
class CLongLong(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 64
|
||
|
||
class CFloat(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 32
|
||
|
||
class CDouble(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 64
|
||
|
||
class CFloat8T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 8
|
||
|
||
class CFloat16T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 16
|
||
|
||
class CFloat32T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 32
|
||
|
||
class CFloat64T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 64
|
||
|
||
class CFloat128T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 128
|
||
|
||
class CVoid(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: Optional[bool] = None
|
||
self.Size: int = 0
|
||
|
||
class CUnsigned(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 32
|
||
|
||
class CUnsignedChar(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 8
|
||
|
||
class CUnsignedInt(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 32
|
||
|
||
class CUnsignedShort(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 16
|
||
|
||
class CUnsignedLong(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = _UNSIGNED_LONG_SIZE
|
||
|
||
class CUnsignedLongLong(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 64
|
||
|
||
class CSignedChar(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 8
|
||
|
||
@_marker_base
|
||
class CStruct(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED})
|
||
def __init__(self, value: Any = None, name: Optional[str] = None) -> None:
|
||
self.name: Optional[str] = name
|
||
super().__init__(value)
|
||
|
||
@_marker_base
|
||
class CUnion(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
@_marker_base
|
||
class CEnum(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
Enum = CEnum
|
||
|
||
@_marker_base
|
||
class REnum(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE, CType.NAMED})
|
||
tag: int = 0 # 无用,只是个标记
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
'''
|
||
class Object(CType):
|
||
"""Python 对象类型,用于支持类方法外联函数"""
|
||
position = frozenset({CType.BASE, CType.NAMED})
|
||
def __init__(self, value=None):
|
||
super().__init__(value)
|
||
def __call__(self, cls):
|
||
return cls
|
||
'''
|
||
def Object() -> None:
|
||
pass
|
||
|
||
def CVTable() -> None:
|
||
pass
|
||
|
||
def NoVTable() -> None:
|
||
"""标记类为非多态继承基类:被子类继承时字段直接展平嵌入,不生成 vtable,避免 vtable 开销。
|
||
区别于 @t.CVTable(启用多态 vtable)。对应 C++ 的非多态继承(struct A : B {} 无 virtual)。"""
|
||
pass
|
||
|
||
def TLS() -> None:
|
||
"""标记函数为 TLS 初始化函数,首次调用时执行,后续调用跳过。
|
||
编译器自动生成全局标志变量和一次性执行检查代码。
|
||
"""
|
||
pass
|
||
|
||
# Object 和 CVTable 是普通函数,Exception 是 Python 内建类型,Enum 是 CEnum 的别名
|
||
# 这些名称无法通过 @_marker_base 装饰器自动注册,需手动添加到 _MARKER_BASES
|
||
# TLS 是函数装饰器标记,由编译器在函数处理阶段识别
|
||
_MARKER_BASES.update({'Object', 'CVTable', 'Exception', 'Enum'})
|
||
|
||
CTypedef: TypeAlias = TypeAlias
|
||
|
||
class _CTypedef(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.NAMED})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
|
||
class CAuto(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CRegister(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CStatic(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CExtern(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CConst(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.TYPE_QUALIFIER})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CInline(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CExport(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CVolatile(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.TYPE_QUALIFIER})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CSizeT(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = _SIZE_T_SIZE
|
||
|
||
class CInt8T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 8
|
||
|
||
class CInt16T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 16
|
||
|
||
class CInt32T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 32
|
||
|
||
class CInt64T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = 64
|
||
|
||
class CUInt8T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 8
|
||
|
||
class CUInt16T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 16
|
||
|
||
class CUInt32T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 32
|
||
|
||
class CUInt64T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 64
|
||
|
||
class CIntPtrT(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = _INTPTR_T_SIZE
|
||
|
||
class CUIntPtrT(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = _UINTPTR_T_SIZE
|
||
|
||
class CPtrDiffT(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = _PTRDIFF_T_SIZE
|
||
|
||
class CWCharT(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = True
|
||
self.Size: int = _WCHAR_T_SIZE
|
||
|
||
class CChar8T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 8
|
||
|
||
class CChar16T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 16
|
||
|
||
class CChar32T(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 32
|
||
|
||
class CBool(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
self.IsSigned: bool = False
|
||
self.Size: int = 8
|
||
|
||
T = TypeVar("T")
|
||
|
||
class CPtr(CType, Generic[T]):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.POINTER})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CNeedPtr(CPtr):
|
||
"""函数签名注解:自动取地址(仅对非指针值)。
|
||
用作参数类型时,编译器在调用处自动将非指针值取地址为指针。
|
||
若参数已经是指针,则不做操作。"""
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.POINTER})
|
||
auto_addr_mode: ClassVar[str] = 'need'
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CAutoPtr(CPtr):
|
||
"""函数签名注解:无条件取地址。
|
||
用作参数类型时,编译器在调用处无条件将值取地址为指针,
|
||
即使值本身已经是指针也会再取一层地址。"""
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.POINTER})
|
||
auto_addr_mode: ClassVar[str] = 'always'
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CTypeDefault(CType):
|
||
"""用于存储 C 类型默认值/初始化的包装类
|
||
|
||
当使用 t.CStatic.__set_default__(open=mouse_open, ...) 时创建
|
||
"""
|
||
def __init__(self, BaseType: Any, **kwargs: Any) -> None:
|
||
super().__init__()
|
||
self.BaseType: Any = BaseType
|
||
self.defaults: dict[str, Any] = kwargs
|
||
self.position: frozenset[str] = BaseType.position if hasattr(BaseType, 'position') else CType.BASE
|
||
|
||
def __repr__(self) -> str:
|
||
return f'CTypeDefault({self.BaseType}, {self.defaults})'
|
||
|
||
class CArrayPtr(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.POINTER})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CArray(CType):
|
||
"""栈上固定数组类型注解。
|
||
用法: names: t.CArray[VOIDPTR, 32] # void*[32]
|
||
data: t.CArray[t.CInt, 64] # int[64]
|
||
第一个参数为元素类型,第二个参数为数组大小(整数或常量名)。"""
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.ARRAY})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
def __class_getitem__(cls, item: Any) -> type:
|
||
return cls
|
||
|
||
class CDefine(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class CPass(CType):
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.BASE})
|
||
def __init__(self, value: Any = None) -> None:
|
||
super().__init__(value)
|
||
|
||
class State(CType):
|
||
"""状态标记,用于仅声明不定义,等价于 CExport | CExtern"""
|
||
position: ClassVar[frozenset[str]] = frozenset({CType.PREFIX, CType.STORAGE_CLASS})
|
||
|
||
@staticmethod
|
||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||
"""处理 t.State() 调用"""
|
||
return ['t.State']
|
||
|
||
class Postdefinition:
|
||
def __init__(self, c: Any) -> None:
|
||
pass
|
||
|
||
class Bit:
|
||
def __init__(self, i: Any) -> None:
|
||
pass
|
||
|
||
class BigEndian(CType):
|
||
"""大端序(Big-Endian)字节序标记类
|
||
|
||
用于标记结构体成员应使用大端序存储。
|
||
在小端序平台(如x86)上读取时,会自动进行字节交换。
|
||
|
||
用法示例:
|
||
class MyStruct:
|
||
a: t.CInt | t.BigEndian # 大端序存储的整数
|
||
"""
|
||
IsSigned: ClassVar[bool] = True
|
||
Size: ClassVar[int] = 32
|
||
Align: ClassVar[int] = 32
|
||
|
||
class LittleEndian(CType):
|
||
"""小端序(Little-Endian)字节序标记类
|
||
|
||
用于标记结构体成员应使用小端序存储。
|
||
在小端序平台(如x86)上读取时,不需要进行字节交换。
|
||
|
||
用法示例:
|
||
class MyStruct:
|
||
b: t.CInt | t.LittleEndian # 小端序存储的整数
|
||
"""
|
||
IsSigned: ClassVar[bool] = True
|
||
Size: ClassVar[int] = 32
|
||
Align: ClassVar[int] = 32
|
||
|
||
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: list[str] = ASM_DESCR.ALL
|
||
|
||
|
||
class attr:
|
||
"""C 语言 __attribute__ 属性操作类型"""
|
||
|
||
@staticmethod
|
||
def noreturn() -> str:
|
||
return "noreturn"
|
||
|
||
@staticmethod
|
||
def format(printf: Any, arg1: Any, arg2: Any) -> str:
|
||
return f"format({printf}, {arg1}, {arg2})"
|
||
|
||
@staticmethod
|
||
def section(name: str) -> str:
|
||
return f'section("{name}")'
|
||
|
||
@staticmethod
|
||
def aligned(bytes: int) -> str:
|
||
return f"aligned({bytes})"
|
||
|
||
@staticmethod
|
||
def packed() -> str:
|
||
return "packed"
|
||
|
||
@staticmethod
|
||
def unused() -> str:
|
||
return "unused"
|
||
|
||
@staticmethod
|
||
def used() -> str:
|
||
return "used"
|
||
|
||
@staticmethod
|
||
def weak() -> str:
|
||
return "weak"
|
||
|
||
@staticmethod
|
||
def alias(name: str) -> str:
|
||
return f'alias("{name}")'
|
||
|
||
@staticmethod
|
||
def visibility(type: str) -> str:
|
||
return f'visibility("{type}")'
|
||
|
||
@staticmethod
|
||
def constructor() -> str:
|
||
return "constructor"
|
||
|
||
@staticmethod
|
||
def destructor() -> str:
|
||
return "destructor"
|
||
|
||
@staticmethod
|
||
def always_inline() -> str:
|
||
return "always_inline"
|
||
|
||
@staticmethod
|
||
def noinline() -> str:
|
||
return "noinline"
|
||
|
||
@staticmethod
|
||
def pure() -> str:
|
||
return "pure"
|
||
|
||
@staticmethod
|
||
def const() -> str:
|
||
return "const"
|
||
|
||
@staticmethod
|
||
def malloc() -> str:
|
||
return "malloc"
|
||
|
||
@staticmethod
|
||
def alloc_size(n: int) -> str:
|
||
return f"alloc_size({n})"
|
||
|
||
@staticmethod
|
||
def warn_unused_result() -> str:
|
||
return "warn_unused_result"
|
||
|
||
@staticmethod
|
||
def deprecated(msg: Optional[str] = None) -> str:
|
||
if msg:
|
||
return f'deprecated("{msg}")'
|
||
return "deprecated"
|
||
|
||
@staticmethod
|
||
def fallthrough() -> str:
|
||
return "fallthrough"
|
||
|
||
@staticmethod
|
||
def likely() -> str:
|
||
return "likely"
|
||
|
||
@staticmethod
|
||
def unlikely() -> str:
|
||
return "unlikely"
|
||
|
||
@staticmethod
|
||
def hot() -> str:
|
||
return "hot"
|
||
|
||
@staticmethod
|
||
def cold() -> str:
|
||
return "cold"
|
||
|
||
@staticmethod
|
||
def interrupt() -> str:
|
||
return "interrupt"
|
||
|
||
@staticmethod
|
||
def naked() -> str:
|
||
return "naked"
|
||
|
||
@staticmethod
|
||
def sentinel(n: int = 0) -> str:
|
||
return f"sentinel({n})"
|
||
|
||
@staticmethod
|
||
def nonnull(*args: Any) -> str:
|
||
if args:
|
||
return f"nonnull({', '.join(map(str, args))})"
|
||
return "nonnull"
|
||
|
||
@staticmethod
|
||
def returns_nonnull() -> str:
|
||
return "returns_nonnull"
|
||
|
||
@staticmethod
|
||
def access(mode: Any, *args: Any) -> str:
|
||
return f"access({mode}, {', '.join(map(str, args))})"
|
||
|
||
@staticmethod
|
||
def cleanup(func: str) -> str:
|
||
return f'cleanup({func})'
|
||
|
||
@staticmethod
|
||
def transparent_union() -> str:
|
||
return "transparent_union"
|
||
|
||
@staticmethod
|
||
def mode(mode_name: str) -> str:
|
||
return f"mode({mode_name})"
|
||
|
||
@staticmethod
|
||
def vector_size(bytes: int) -> str:
|
||
return f"vector_size({bytes})"
|
||
|
||
@staticmethod
|
||
def target(string: str) -> str:
|
||
return f'target("{string}")'
|
||
|
||
@staticmethod
|
||
def optimize(level: str) -> str:
|
||
return f'optimize("{level}")'
|
||
|
||
@staticmethod
|
||
def no_instrument_function() -> str:
|
||
return "no_instrument_function"
|
||
|
||
@staticmethod
|
||
def no_sanitize(type: str) -> str:
|
||
return f"no_sanitize({type})"
|
||
|
||
@staticmethod
|
||
def no_stack_protector() -> str:
|
||
return "no_stack_protector"
|
||
|
||
@staticmethod
|
||
def stack_protector() -> str:
|
||
return "stack_protector"
|
||
|
||
@staticmethod
|
||
def error(msg: str) -> str:
|
||
return f'error("{msg}")'
|
||
|
||
@staticmethod
|
||
def warning(msg: str) -> str:
|
||
return f'warning("{msg}")'
|
||
|
||
class llvm:
|
||
"""LLVM 函数属性描述符
|
||
|
||
用于在返回类型注解中指定 LLVM 函数属性。
|
||
例如: def foo() -> t.CInt | t.attr.llvm.nobuiltin | t.attr.llvm.nounwind:
|
||
"""
|
||
|
||
# 以下空类仅作为类型注解占位符使用,由 HandlesFunctions._GetAttrLLVMName
|
||
# 从 AST 直接提取属性名(node.attr),不依赖 CName 属性。
|
||
class nobuiltin: pass
|
||
class nounwind: pass
|
||
class noredzone: pass
|
||
class willreturn: pass
|
||
class mustprogress: pass
|
||
class optnone: pass
|
||
class noinline: pass
|
||
class alwaysinline: pass
|
||
class readnone: pass
|
||
class readonly: pass
|
||
class writeonly: pass
|
||
class inaccessiblememonly: pass
|
||
class inaccessiblemem_or_argmemonly: pass
|
||
|
||
|
||
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: ClassVar[Optional[dict[str, type]]] = None
|
||
|
||
@classmethod
|
||
def _build(cls) -> None:
|
||
if cls._name_to_class is not None:
|
||
return
|
||
mod: Optional[types.ModuleType] = sys.modules.get(__name__)
|
||
if mod is None:
|
||
return
|
||
cls._name_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: Any = obj()
|
||
except Exception:
|
||
continue
|
||
pos: frozenset[str] = 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
|
||
# 注册基本类型(有 Size)和命名基本类型(CStruct/CUnion/CEnum/REnum)。
|
||
# 不再依赖 CName 属性,依据 position/Size 推断。
|
||
if getattr(inst, 'Size', None) is not None or CType.NAMED in pos:
|
||
cls._name_to_class[name] = obj
|
||
|
||
@classmethod
|
||
def GetClassByName(cls, name: str) -> Optional[type]:
|
||
"""根据 Python 类名获取 CType 类 (如 'CInt32T' -> t.CInt32T)"""
|
||
cls._build()
|
||
return cls._name_to_class.get(name)
|
||
|
||
@staticmethod
|
||
def CTypeToLLVM(ctype_class: Optional[type]) -> 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: frozenset[str] = 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: Any = ctype_class()
|
||
except Exception:
|
||
return 'i8*'
|
||
size: Optional[int] = getattr(inst, 'Size', None)
|
||
is_signed: Optional[bool] = 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: dict[int, str] = {8: 'half', 16: 'half', 32: 'float', 64: 'double', 128: 'fp128'}
|
||
return float_map.get(size, f'f{size}')
|
||
return f'i{size}'
|
||
|
||
_llvm_to_ctype_cache: ClassVar[Optional[dict[str, type]]] = None
|
||
|
||
@classmethod
|
||
def LLVMToCType(cls, llvm_str: str) -> Optional[type]:
|
||
if cls._llvm_to_ctype_cache is None:
|
||
cls._build()
|
||
cls._llvm_to_ctype_cache = {}
|
||
for name, ctype_cls in cls._name_to_class.items():
|
||
pos: frozenset[str] = getattr(ctype_cls, 'position', frozenset())
|
||
if CType.PREFIX in pos and CType.BASE not in pos:
|
||
continue
|
||
llvm_key: str = cls.CTypeToLLVM(ctype_cls)
|
||
if llvm_key and llvm_key not in cls._llvm_to_ctype_cache:
|
||
cls._llvm_to_ctype_cache[llvm_key] = ctype_cls
|
||
return cls._llvm_to_ctype_cache.get(llvm_str)
|
||
|
||
@classmethod
|
||
def NameToLLVM(cls, name: str) -> Optional[str]:
|
||
"""根据 Python 类型名推导 LLVM IR 类型 (如 'CFloat64T' -> 'double')
|
||
|
||
修饰符类型 (CConst, CStatic 等) 返回空字符串。
|
||
指针类型 (CPtr) 返回 'i8*'。
|
||
未知类型返回 None。
|
||
"""
|
||
cls._build()
|
||
mod: Optional[types.ModuleType] = sys.modules.get(__name__)
|
||
if mod and hasattr(mod, name):
|
||
obj: Any = getattr(mod, name)
|
||
if isinstance(obj, type) and issubclass(obj, CType):
|
||
return cls.CTypeToLLVM(obj)
|
||
return None
|
||
|
||
@classmethod
|
||
def ResolveName(cls, name: str) -> Optional[tuple[type, int]]:
|
||
"""解析类型名到 (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 后缀的隐式类型推断,以避免违反类型自由原则。
|
||
"""
|
||
cls._build()
|
||
direct: Optional[type] = cls._name_to_class.get(name)
|
||
if direct is not None:
|
||
pos: frozenset[str] = getattr(direct, 'position', frozenset())
|
||
ptr_level: int = 1 if CType.POINTER in pos and CType.BASE not in pos else 0
|
||
return (direct, ptr_level)
|
||
# C 基本类型名 / Python 内置类型名 → Python 类名硬编码表。
|
||
# 仅保留语言内置名称;stdint.h 类型名由 stdint.py 的 typedef 提供。
|
||
_CNAME_ALIAS: dict[str, str] = {
|
||
# Python 内置类型名
|
||
'bool': 'CBool', 'int': 'CInt', 'float': 'CFloat',
|
||
# C 基本类型名
|
||
'char': 'CChar', 'short': 'CShort', 'long': 'CLong',
|
||
'long long': 'CLongLong', 'double': 'CDouble', 'void': 'CVoid',
|
||
'unsigned': 'CUnsigned', 'signed': 'CInt', 'signed int': 'CInt',
|
||
'signed char': 'CSignedChar',
|
||
'unsigned char': 'CUnsignedChar', 'unsigned int': 'CUnsignedInt',
|
||
'unsigned short': 'CUnsignedShort', 'unsigned long': 'CUnsignedLong',
|
||
'unsigned long long': 'CUnsignedLongLong',
|
||
}
|
||
cname_alias: Optional[str] = _CNAME_ALIAS.get(name)
|
||
if cname_alias is not None:
|
||
alias_cls: Optional[type] = cls._name_to_class.get(cname_alias)
|
||
if alias_cls is not None:
|
||
return (alias_cls, 0)
|
||
return None |