fix(tpc): 收紧「类身份」判据 + REnum 变体载荷解析失败不再被吞
承接 02d89b09:上一版判据"BaseType 是 CVoid ⇒ 类型信息丢失"**误伤 REnum** —— REnum 类型条目本身 `BaseType=None`,`T | t.CPtr` 合并时 `_MergeAllComponentTypes` 末尾会把空 BaseType 默认填成 CVoid,但 IsRenum/IsStruct/Name 齐备,`_ctype_to_llvm` 仍能解析出 `%<sha1>.T*`。于是合法注解 `Pointee: rawptr[LLVMType]`(REnum 变体载荷) 被打成致命错误,异常又在此处被上层吞掉 ⇒ 变体只剩 __tag。 两处修正: 1) HandlesBase._CheckPtrAnnotationKeepsClass:判据收紧为「BaseType 是 CVoid **且 没有任何类身份**(IsStruct / IsRenum / IsEnum / Name 全空)」才失败。 2) HandlesImports REnum 变体载荷注册:历史上 `CollectAnnAssignMember` 的异常被上层 吞掉、`parsed` 为 None 时静默跳过 ⇒ class_members 只剩 __tag、变体循环中断 (现场同前缀 structs 键只有 LLVMType_Int / LLVMType_Ptr,源顺序其后还有 Func/Array/Struct/…),进而使变体构造丢载荷、match 捕获绑不上。现改为: - 只把 AnnAssign 当载荷声明(pass / docstring 合法跳过,如 `class Void: pass`); - 解析抛异常 ⇒ fail-fast 并带上原异常(拒绝留下只有 __tag 的成员表); - 解析返回 None ⇒ 同样 fail-fast。
This commit is contained in:
1 parent
53bde9157e
commit
dab0823f5c
2 files changed
+37
-6
No files matched your search
@@ -1099,13 +1099,21 @@ class BaseHandle:
|
||||
|
||||
只拦"必属类型信息丢失"的组合:内层节点(Name / Attribute)的名字在
|
||||
`Gen.structs`(本模块已建)或 `Gen._struct_sha1_map`(预扫描的类→模块映射)
|
||||
中有类定义,而解析出的 `BaseType` 却是 `t.CVoid`。其余一律放行
|
||||
中有类定义,而解析出的 `BaseType` 是 `t.CVoid` **且没有任何类身份**
|
||||
(IsStruct / IsRenum / IsEnum / Name 全空)。其余一律放行
|
||||
(`rawptr[rawptr]` 这类本就 void 基座的多层指针、模块名、泛型特化实参等)。
|
||||
"""
|
||||
if Info is None or Info.BaseType is None:
|
||||
return
|
||||
if not (Info.BaseType is t.CVoid or isinstance(Info.BaseType, t.CVoid)):
|
||||
return
|
||||
# 只要还带着任何"类身份"(IsStruct / IsRenum / IsEnum / Name),就不是信息丢失:
|
||||
# REnum 类型条目本身 BaseType=None,`T | t.CPtr` 合并后会被默认填成 CVoid,但
|
||||
# IsRenum/IsStruct/Name 齐备,_ctype_to_llvm 仍能解析出 %<sha1>.T* —— 误判会
|
||||
# 把合法注解(如 REnum 变体载荷 `Pointee: rawptr[LLVMType]`)打成致命错误。
|
||||
if (getattr(Info, 'IsStruct', False) or getattr(Info, 'IsRenum', False)
|
||||
or getattr(Info, 'IsEnum', False) or getattr(Info, 'Name', None)):
|
||||
return
|
||||
Inner: ast.AST | None = None
|
||||
if isinstance(Annotation, ast.Subscript) and IsPtrSubscriptNode(Annotation, self.Trans.SymbolTable):
|
||||
Inner = Annotation.slice
|
||||
|
||||
@@ -1882,11 +1882,34 @@ class ImportHandle(BaseHandle):
|
||||
Gen.class_members[NestedStructName].append(('__tag', ir.IntType(32)))
|
||||
Gen.class_member_signeds[NestedStructName]['__tag'] = None
|
||||
for nested_item in item.body:
|
||||
parsed = self.CollectAnnAssignMember(nested_item, Gen)
|
||||
if parsed:
|
||||
MName, MType, MTypeInfo = parsed
|
||||
Gen.class_members[NestedStructName].append((MName, MType))
|
||||
Gen.class_member_signeds[NestedStructName][MName] = None
|
||||
# 只把 AnnAssign 当载荷声明;变体体里的 pass / docstring 等
|
||||
# 非声明语句合法跳过(如 `class Void: pass`)。
|
||||
if not isinstance(nested_item, ast.AnnAssign):
|
||||
continue
|
||||
_member_txt: str = ast.unparse(nested_item)
|
||||
try:
|
||||
parsed = self.CollectAnnAssignMember(nested_item, Gen)
|
||||
except Exception as _pe:
|
||||
# 历史上此处异常被上层吞掉 ⇒ 变体只剩 __tag ⇒ 变体构造静默
|
||||
# 丢载荷、match 模式捕获绑不上(现场 LLVMType_Ptr / pointee_cs),
|
||||
# 且循环中断使后续变体(Func/Array/...)整批缺失。改为响亮失败。
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
|
||||
raise _FFE(
|
||||
f"REnum 变体 '{ClassName}.{VariantName}' 的载荷成员 "
|
||||
f"'{_member_txt}' 解析失败:{type(_pe).__name__}: {_pe} "
|
||||
f"—— 拒绝留下只有 __tag 的 class_members"
|
||||
f"(会导致变体构造丢载荷、match 捕获绑定缺失、后续变体整批缺失)"
|
||||
) from _pe
|
||||
if not parsed:
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError as _FFE
|
||||
raise _FFE(
|
||||
f"REnum 变体 '{ClassName}.{VariantName}' 的载荷成员 "
|
||||
f"'{_member_txt}' 未解析出类型(CollectAnnAssignMember 返回 None)"
|
||||
f"—— 同上,拒绝静默降级为无载荷"
|
||||
)
|
||||
MName, MType, MTypeInfo = parsed
|
||||
Gen.class_members[NestedStructName].append((MName, MType))
|
||||
Gen.class_member_signeds[NestedStructName][MName] = None
|
||||
# 当 stub 中没有嵌套变体结构体定义时(_TryLoadStructFromStub 失败),
|
||||
# 使用主 REnum 结构体的 body (max_variant_struct) 创建嵌套变体结构体,
|
||||
# 确保跨模块布局一致。否则 _generate_structs() Step 4 会从 class_members
|
||||
|
||||
Reference in new issue
Block a user