fix(Translator): 类体 CDefine 预扫描扩展 + CDefine 类型修复(i32)

- GenerateLlvmDirect 预扫描扩展到类体 AnnAssign,注册类体 CDefine 常量
  (方法内裸名如 ISINSTANCE_CLASS_MAX 不再解析为 0)
- t.py CDefine Size/IsSigned 覆盖为 32 位有符号,修复 stub 生成 void 类型
- 新增 Test/TpvIsinstanceTest(TPV 侧 isinstance 回归测试)
This commit is contained in:
TermiNexus committed 2026-08-10 21:15:42 +08:00
1 parent 1b89225130
commit 9c2dc45c03
4 files changed
+197 -19

No files matched your search

+33 -19
View File
@@ -74,30 +74,44 @@ class LlvmGeneratorMixin:
# 使用 ConstEvaluator 处理 BinOp/UnaryOp/Name/Attribute/Call
return ConstEvaluator.eval_with_symtab(node, self.SymbolTable)
def _is_cdefine_type(TypeInfo: CTypeInfo | None) -> bool:
"""判断 CTypeInfo 是否对应 t.CDefine 注解"""
return bool(TypeInfo and TypeInfo.BaseType and
((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine))
or isinstance(TypeInfo.BaseType, t.CDefine) or TypeInfo.IsDefine))
def _register_cdefine_constant(NameNode: ast.Name, Annotation: ast.expr, Value: ast.expr) -> None:
"""注册 CDefine 编译期常量(_define_constants + SymbolTable)"""
TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(Annotation)
if not _is_cdefine_type(TypeInfo):
return
val: int | str | float | None = _extract_const_value(Value)
if val is not None:
if not hasattr(Gen, '_define_constants'):
Gen._define_constants: dict[str, int | str | float | bool] = {}
Gen._define_constants[NameNode.id] = val
existing = self.SymbolTable.lookup(NameNode.id)
if not (existing and existing.IsTypedef and existing.OriginalType):
sym_info: _CTypeInfo = _CTypeInfo()
sym_info.IsDefine = True
sym_info.DefineValue = val
self.SymbolTable.insert(NameNode.id, sym_info)
for Node in ast.iter_child_nodes(Tree):
if isinstance(Node, ast.AnnAssign) and isinstance(Node.target, ast.Name) and Node.value:
TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(Node.annotation)
# 治本修复:检查 BaseType 是否为 t.CDefine 实例/子类,或 IsDefine 标志
# IsDefine 由 GetCTypeInfo 对 t.CDefine 注解自动设置
if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine) or TypeInfo.IsDefine):
val: int | str | float | None = _extract_const_value(Node.value)
import sys as _sys
_nm = Node.target.id
# [CD] 仅输出关键常量(FOREGROUND_*, STD_OUTPUT_HANDLE, BACKGROUND_*)
if isinstance(_nm, str) and (_nm.startswith('FOREGROUND_') or _nm.startswith('BACKGROUND_') or 'STD_' in _nm or 'HANDLE' in _nm):
print(f"[CD] extract: '{_nm}' IsDefine={TypeInfo.IsDefine} val={val}", file=_sys.stderr, flush=True)
if val is not None:
if not hasattr(Gen, '_define_constants'):
Gen._define_constants: dict[str, int | str | float | bool] = {}
Gen._define_constants[Node.target.id] = val
existing = self.SymbolTable.lookup(Node.target.id)
if not (existing and existing.IsTypedef and existing.OriginalType):
sym_info: _CTypeInfo = _CTypeInfo()
sym_info.IsDefine = True
sym_info.DefineValue = val
self.SymbolTable.insert(Node.target.id, sym_info)
else:
print(f"[CD] extract: WARN val is None for '{_nm}'", file=_sys.stderr, flush=True)
if _is_cdefine_type(TypeInfo):
_register_cdefine_constant(Node.target, Node.annotation, Node.value)
elif isinstance(Node, ast.ClassDef):
# 类体 CDefine 常量(2026-08-10):供方法内裸名(如 Mixin 的
# ISINSTANCE_CLASS_MAX/MRO_MAX: t.CDefine = N)编译期解析为常量值。
# 原预扫描只用 iter_child_nodes 扫顶层,类体常量不注册 → 方法内
# 裸名解析为 0 → pool.alloc(8*0) 失败(TPV 编译测试 SUBS-NONE)。
for _citem in Node.body:
if isinstance(_citem, ast.AnnAssign) and isinstance(_citem.target, ast.Name) and _citem.value:
_register_cdefine_constant(_citem.target, _citem.annotation, _citem.value)
elif isinstance(Node, ast.Assign):
for target in Node.targets:
if isinstance(target, ast.Name):