fix(tpc): 降级判据改用「注解形态 + 解析结果形状」,放在字段类型唯一漏斗
上一版拦截失效的原因(实测):`class_member_annotations` 全仓**只被声明与读取、从未被
写入**(Step 2 一直是空转),故依赖它的 `_HasDegradedMemberTypes` 恒为 False。改法:
1) SymbolUtils 新增两个**形状判据**(纯判定,不做类型解析):
- IsI8DoublePtrType(T):是否 i8 系两层指针(`i8**`)= `T | t.CPtr` 在 T 类型丢失后
退化成的形状;
- IsClassRefPtrAnnotation(Ann):注解是否「指针包装的类引用」(rawptr[Mod.Class] /
Mod.Class | t.CPtr;内层为非 t/c 模块的 Attribute 或首字母大写裸名)。
2) HandlesBase.CollectAnnAssignMember(字段类型的**唯一漏斗**,覆盖本地类 /
跨模块 .vpi / 嵌套类三条写入链)新增硬判据:注解是类引用指针 **且** 解析结果正是
`i8**` ⇒ 必属类型信息丢失,当场 fail-fast,并打出 CTypeInfo 全字段(BaseType/
PtrCount/IsStruct/IsTypedef/IsEnum/Name)与内层名的符号表条目标志。此前的
`_CheckPtrAnnotationKeepsClass` 只看"void 基座且无类身份",而现场这条链**带 Name/
IsTypedef**(Attribute 分支的 typedef 出口 → BaseType=CVoid 但 Name=类名),正好漏过。
3) StructGen 删除依赖那张空表的 `_HasDegradedMemberTypes` / `_IsI8DoublePtr` /
`_IsClassRefPtrAnnotation` 及 set_body 前的拦截(改由漏斗处兜住,不留死代码)。
现场:Generator.vp:200 `self.ExprGenFstr = SubExprGenFstr`
→ 布局槽 elements[11]=i8** 而声明 %"a7b68c79f39cb4d3.ExprGenFstr"*
This commit is contained in:
1 parent
66de269ebf
commit
7167703ca7
3 files changed
+91
-84
No files matched your search
@@ -15,7 +15,8 @@ from lib.includes.t import CTypeRegistry
|
||||
from lib.core.TypeSpec import TypeSpec, SymbolMeta, FIELD_ROUTES
|
||||
from lib.core.SymbolUtils import (
|
||||
IsPtrSubscriptNode, IsListAnnotation, IsCPtrMarkerNode,
|
||||
FlattenUnionOperands, FixedArrayKeywordAnnotationError)
|
||||
FlattenUnionOperands, IsI8DoublePtrType, IsClassRefPtrAnnotation,
|
||||
FixedArrayKeywordAnnotationError)
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
|
||||
|
||||
@@ -1091,6 +1092,46 @@ class BaseHandle:
|
||||
# (llvmlite set_body 只能设一次),后期只修表不修体(现场:Generator 第 3/11
|
||||
# 槽 i8**)。此处响亮失败并附判据,使降级**当场暴露**而非留到赋值时报"层数不同"。
|
||||
self._CheckPtrAnnotationKeepsClass(item.annotation, TypeInfo, VarName, AnnotationText)
|
||||
# 形状判据(更硬的一条):注解形态是「**指针包装的类引用**」而解析结果正是
|
||||
# `i8**`(= void 基座两层,T 的类型被丢掉)⇒ 必属降级,直接响亮失败并把两侧
|
||||
# 证据打全。放在字段类型的**唯一漏斗**里,覆盖全部"按注解推导成员类型"的写入链
|
||||
# (本地类 / 跨模块 .vpi / 嵌套类)。
|
||||
if (IsClassRefPtrAnnotation(item.annotation, self.Trans.SymbolTable)
|
||||
and IsI8DoublePtrType(MemberType)):
|
||||
_inner_name: str = ''
|
||||
_inner_node: Any = (item.annotation.slice
|
||||
if isinstance(item.annotation, ast.Subscript) else None)
|
||||
if isinstance(_inner_node, ast.Attribute):
|
||||
_inner_name = _inner_node.attr
|
||||
elif isinstance(_inner_node, ast.Name):
|
||||
_inner_name = _inner_node.id
|
||||
_sym: Any = None
|
||||
try:
|
||||
_sym = self.Trans.SymbolTable.lookup(_inner_name) if _inner_name else None
|
||||
except Exception:
|
||||
_sym = None
|
||||
_gen: Any = getattr(self.Trans, 'LlvmGen', None)
|
||||
_structs_hit: str = (
|
||||
'有' if (_gen is not None and _inner_name in getattr(_gen, 'structs', {})) else '无')
|
||||
_sha1_hit: Any = (
|
||||
getattr(_gen, '_struct_sha1_map', {}).get(_inner_name) if _gen is not None else None)
|
||||
raise ValueError(
|
||||
f"[FATAL] 成员 '{VarName}' 的注解 '{AnnotationText}' 是**类引用指针**,"
|
||||
f"却被解析成 {MemberType}(void 基座两层 = 类型信息丢失)—— 拒绝降级:"
|
||||
f"CTypeInfo(BaseType={getattr(TypeInfo, 'BaseType', None)} "
|
||||
f"PtrCount={getattr(TypeInfo, 'PtrCount', None)} "
|
||||
f"IsStruct={getattr(TypeInfo, 'IsStruct', None)} "
|
||||
f"IsTypedef={getattr(TypeInfo, 'IsTypedef', None)} "
|
||||
f"IsEnum={getattr(TypeInfo, 'IsEnum', None)} "
|
||||
f"Name={getattr(TypeInfo, 'Name', None)});内层名='{_inner_name}' "
|
||||
f"符号表[该名] => IsTypedef={getattr(_sym, 'IsTypedef', None)} "
|
||||
f"BaseType={getattr(_sym, 'BaseType', None)} "
|
||||
f"PtrCount={getattr(_sym, 'PtrCount', None)} "
|
||||
f"IsStruct={getattr(_sym, 'IsStruct', None)} "
|
||||
f"IsRenum={getattr(_sym, 'IsRenum', None)} "
|
||||
f"IsModuleAlias={getattr(_sym, 'IsModuleAlias', None)};"
|
||||
f"Gen.structs 命中={_structs_hit} _struct_sha1_map 命中={_sha1_hit!r}"
|
||||
)
|
||||
return VarName, MemberType, TypeInfo
|
||||
|
||||
def _CheckPtrAnnotationKeepsClass(self, Annotation: ast.AST, Info: CTypeInfo | None,
|
||||
|
||||
Reference in new issue
Block a user