尝试进行 Qt 测试,增加了 AI 人机调试工具 _console,以及 TransPyV 进行修正

This commit is contained in:
2026-07-21 14:41:22 +08:00
parent a277ded8d4
commit 135aa05485
311 changed files with 7084 additions and 2131 deletions

View File

@@ -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=0CType 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