1283 lines
39 KiB
Python
1283 lines
39 KiB
Python
# 类型定义模块
|
||
|
||
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() |