尝试进行 Qt 测试,增加了 AI 人机调试工具 _console,以及 TransPyV 进行修正
This commit is contained in:
@@ -292,6 +292,22 @@ class BaseGenMixin:
|
||||
return existing
|
||||
if clean_name in {'typedef', 'CType', 'CVolatile', 'CEnum', 'CUnion', 'CStruct', 'enum', 'REnum', 'renum', 'Void', 'void'}:
|
||||
return ir.IntType(8)
|
||||
# typing.Any 是"任意类型"标记,应解析为 i8*(通用指针),
|
||||
# 而非创建为 opaque 结构体(否则包含 Any 字段的结构体会变成 unsized)。
|
||||
if clean_name == 'Any':
|
||||
return ir.IntType(8).as_pointer()
|
||||
# t.CType 的基本类型子类(CInt/CChar/CSizeT/CLong/CFloat/CDouble 等,
|
||||
# position 含 BASE 且 Size>0)有具体 LLVM 类型,应直接返回对应的
|
||||
# ir.IntType/ir.FloatType/ir.DoubleType,而非创建结构体。
|
||||
# _is_ctype_marker_name 对这些类型返回 False(不跳过),需要在此处拦截。
|
||||
_basic_llvm_type: ir.Type | None = self._try_resolve_ctype_basic(clean_name)
|
||||
if _basic_llvm_type is not None:
|
||||
return _basic_llvm_type
|
||||
# t.CType 及其子类是"类型强转"标记,不应被编译为真实结构体。
|
||||
# 动态检查 t 模块中所有 CType 子类名(排除 CStruct/CEnum/CUnion/REnum 子类,
|
||||
# 因为用户定义的结构体类继承自它们,需要被创建为结构体)。
|
||||
if self._is_ctype_marker_name(clean_name):
|
||||
return ir.IntType(8)
|
||||
if self.SymbolTable:
|
||||
Entry: _CTypeInfo | None = self.SymbolTable.lookup(clean_name)
|
||||
if Entry and Entry.IsTypedef:
|
||||
@@ -409,8 +425,93 @@ class BaseGenMixin:
|
||||
pass
|
||||
return 0 # 标记为 typedef,但位宽为 0(非整数)
|
||||
|
||||
# t.CType 及其子类是"类型强转"标记,不应被创建为结构体。
|
||||
# 动态检查 t 模块中所有 CType 子类名(排除 CStruct/CEnum/CUnion/REnum 子类)。
|
||||
# 返回 0 标记为 typedef,使 _get_or_create_struct 走 typedef 路径返回 i8。
|
||||
if self._is_ctype_marker_name(name):
|
||||
return 0
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _is_ctype_marker_name(name: str) -> bool:
|
||||
"""检查名称是否是 t.CType 的"类型强转"标记子类名。
|
||||
|
||||
只有 position 不含 BASE 的纯修饰符/标记类型(CPtr/CVolatile/CConst/
|
||||
CInline/CStatic/CExtern/CExport/CRegister/CAuto/_CTypedef/CTypeDefault 等)
|
||||
才应该跳过结构体创建。有 BASE position 的基本类型(CInt/CChar/CSizeT/
|
||||
CLong/CFloat/CDouble 等)有具体大小,应被正常解析为对应宽度的整数/浮点。
|
||||
|
||||
CStruct/CEnum/CUnion/REnum 的用户子类是合法结构体,需要被创建。
|
||||
|
||||
注意:CTypeRegistry.GetClassByName 会跳过 CType 本身和 CTypeDefault,
|
||||
所以这里直接用 getattr(t, name) 检查 t 模块属性。
|
||||
|
||||
Returns:
|
||||
True 如果 name 是 CType 标记子类名(应跳过结构体创建)
|
||||
"""
|
||||
if not name:
|
||||
return False
|
||||
# 去除可能的 SHA1 前缀(如 "abc123.CPtr" -> "CPtr")
|
||||
short_name: str = name.split('.')[-1] if '.' in name else name
|
||||
# 直接查 t 模块属性(CTypeRegistry._build 会跳过 CType/CTypeDefault/BigEndian/LittleEndian)
|
||||
t_cls: Any = getattr(_t, short_name, None)
|
||||
if not isinstance(t_cls, type) or not issubclass(t_cls, _t.CType):
|
||||
return False
|
||||
# 排除 CStruct/CEnum/CUnion/REnum 子类(它们是命名类型的基类,
|
||||
# 用户定义的结构体继承自它们,需要被创建为结构体)
|
||||
if issubclass(t_cls, (_t.CStruct, _t.CEnum, _t.REnum, _t.CUnion)):
|
||||
return False
|
||||
# 基本类型(position 含 BASE 且 Size > 0)有具体大小,不应跳过
|
||||
# (CInt→i32, CChar→i8, CSizeT→i64, CLong→i64, CFloat→f32 等)
|
||||
# CVoid 虽含 BASE 但 Size=0,CType Size=None,仍需跳过
|
||||
if _t.CType.BASE in t_cls.position:
|
||||
# 检查实例的 Size(类属性可能未设置,用实例获取)
|
||||
try:
|
||||
inst = t_cls()
|
||||
size_val = getattr(inst, 'Size', None)
|
||||
if size_val is not None and size_val > 0:
|
||||
return False
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
def _try_resolve_ctype_basic(self, name: str) -> ir.Type | None:
|
||||
"""尝试将 t.CType 的基本类型子类名解析为对应的 LLVM 基本类型。
|
||||
|
||||
仅对 t 模块内的 CType 基本类型子类(CInt/CChar/CSizeT/CLong/CFloat/
|
||||
CDouble 等,即 position 含 BASE 且 Size>0)生效,返回对应的
|
||||
ir.IntType/ir.FloatType/ir.DoubleType。
|
||||
|
||||
CStruct/CEnum/CUnion/REnum 子类不在此处理(用户自定义结构体需要被
|
||||
创建为结构体)。CVoid/CType/CPtr 等无 Size 或 Size=0 的类型也不在此
|
||||
处理(应通过 _is_ctype_marker_name 跳过结构体创建)。
|
||||
|
||||
Returns:
|
||||
对应的 ir.Type,或 None 表示不是基本类型,需要继续走结构体创建路径。
|
||||
"""
|
||||
if not name:
|
||||
return None
|
||||
short_name: str = name.split('.')[-1] if '.' in name else name
|
||||
cls: Any = getattr(_t, short_name, None)
|
||||
if not isinstance(cls, type) or not issubclass(cls, _t.CType):
|
||||
return None
|
||||
if issubclass(cls, (_t.CStruct, _t.CEnum, _t.REnum, _t.CUnion)):
|
||||
return None
|
||||
if _t.CType.BASE not in getattr(cls, 'position', frozenset()):
|
||||
return None
|
||||
try:
|
||||
inst = cls()
|
||||
size_val = getattr(inst, 'Size', None)
|
||||
if size_val is None or size_val <= 0:
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
llvm_str: str | None = CTypeRegistry.NameToLLVM(short_name)
|
||||
if not llvm_str:
|
||||
return None
|
||||
return self._type_str_to_llvm(llvm_str)
|
||||
|
||||
def _set_node_info(self, node: ast.AST, extra_info: str = "") -> None:
|
||||
if hasattr(node, 'lineno'):
|
||||
self._current_lineno = node.lineno
|
||||
|
||||
Reference in New Issue
Block a user