From dab0823f5cb684cd49fda55277dc52d1be4a4ff1 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 29 Sep 2026 11:24:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpc):=20=E6=94=B6=E7=B4=A7=E3=80=8C?= =?UTF-8?q?=E7=B1=BB=E8=BA=AB=E4=BB=BD=E3=80=8D=E5=88=A4=E6=8D=AE=20+=20RE?= =?UTF-8?q?num=20=E5=8F=98=E4=BD=93=E8=BD=BD=E8=8D=B7=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E4=B8=8D=E5=86=8D=E8=A2=AB=E5=90=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 承接 02d89b09:上一版判据"BaseType 是 CVoid ⇒ 类型信息丢失"**误伤 REnum** —— REnum 类型条目本身 `BaseType=None`,`T | t.CPtr` 合并时 `_MergeAllComponentTypes` 末尾会把空 BaseType 默认填成 CVoid,但 IsRenum/IsStruct/Name 齐备,`_ctype_to_llvm` 仍能解析出 `%.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。 --- lib/core/Handles/HandlesBase.py | 10 ++++++++- lib/core/Handles/HandlesImports.py | 33 +++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/core/Handles/HandlesBase.py b/lib/core/Handles/HandlesBase.py index 50abbb5..7fea4c7 100644 --- a/lib/core/Handles/HandlesBase.py +++ b/lib/core/Handles/HandlesBase.py @@ -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 仍能解析出 %.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 diff --git a/lib/core/Handles/HandlesImports.py b/lib/core/Handles/HandlesImports.py index 317dcdc..6620688 100644 --- a/lib/core/Handles/HandlesImports.py +++ b/lib/core/Handles/HandlesImports.py @@ -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