From 02d89b090004cf12a93c696c0d54909cd581c578 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 29 Sep 2026 00:21:39 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpc):=20=E5=AD=97=E6=AE=B5=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E3=80=8C=E5=86=85=E5=B1=82=E6=98=AF=E7=B1=BB=E5=8D=B4?= =?UTF-8?q?=E6=88=90=E9=80=9A=E7=94=A8=E6=8C=87=E9=92=88=E3=80=8D=E5=BD=93?= =?UTF-8?q?=E5=9C=BA=20fail-fast=EF=BC=88=E9=99=8D=E7=BA=A7=E6=BA=90?= =?UTF-8?q?=E5=A4=B4=E5=AE=9A=E4=BD=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 承接 b8ed33a2 / 7fb0e498:前两者修的是**结果**(错位 body),本次收**源头** —— class_members 在某个早期 pass 被解析出 i8**(void 基座 + 2 层),随后被冻进 struct body。CollectAnnAssignMember 是字段类型的唯一汇总点,在此加判据式 fail-fast: 判据(只拦"必属类型信息丢失"的组合):注解是指针包装(rawptr[T] / t.CPtr[T] / 裸名 CPtr[T] / `T | t.CPtr` 联合)且其**内层节点(Name/Attribute)的名字在 Gen.structs 或 Gen._struct_sha1_map 中有类定义**,而解析出的 BaseType 却是 t.CVoid ⇒ 必定是解析路径把类丢了,响亮失败并附完整判据: 解析结果 BaseType/PtrCount/IsStruct/IsTypedef/Name 符号表[内层名] => IsTypedef/BaseType/PtrCount/IsStruct/IsRenum/IsModuleAlias/IsEnumMember Gen.structs 命中 / _struct_sha1_map 命中 放行:rawptr[rawptr] 这类本就 void 基座的多层指针、模块名、泛型特化实参(内层非 Name/Attribute)—— 不误伤合法写法。 --- lib/core/Handles/HandlesBase.py | 66 ++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/core/Handles/HandlesBase.py b/lib/core/Handles/HandlesBase.py index 503d675..090d953 100644 --- a/lib/core/Handles/HandlesBase.py +++ b/lib/core/Handles/HandlesBase.py @@ -14,7 +14,8 @@ from lib.includes import t from lib.includes.t import CTypeRegistry from lib.core.TypeSpec import TypeSpec, SymbolMeta, FIELD_ROUTES from lib.core.SymbolUtils import ( - IsPtrSubscriptNode, IsListAnnotation, FixedArrayKeywordAnnotationError) + IsPtrSubscriptNode, IsListAnnotation, IsCPtrMarkerNode, + FlattenUnionOperands, FixedArrayKeywordAnnotationError) from lib.core.VLogger import get_logger as _vlog @@ -1044,8 +1045,71 @@ class BaseHandle: f"IsTypedef={getattr(TypeInfo, 'IsTypedef', None)} " f"Name={getattr(TypeInfo, 'Name', None)})—— 拒绝静默退化为 i8*" ) + # 「内层是类引用却解析成通用指针」fail-fast(降级源头定位): + # `rawptr[Mod.Class]` / `Mod.Class | t.CPtr` 的语义是"指向该类",内层若确实是 + # 已定义类,解析结果必须带该类 BaseType;退化成 void 基座(i8* / 多一层 i8**) + # 就是类型信息被丢掉 —— 该值一旦进 class_members 就会被冻进 struct body + # (llvmlite set_body 只能设一次),后期只修表不修体(现场:Generator 第 3/11 + # 槽 i8**)。此处响亮失败并附判据,使降级**当场暴露**而非留到赋值时报"层数不同"。 + self._CheckPtrAnnotationKeepsClass(item.annotation, TypeInfo, VarName, AnnotationText) return VarName, MemberType, TypeInfo + def _CheckPtrAnnotationKeepsClass(self, Annotation: ast.AST, Info: CTypeInfo | None, + MemberName: str, AnnotationText: str) -> None: + """指针包装注解的内层是**已定义类**时,解析结果不得退化成 void 基座(fail-fast)。 + + 只拦"必属类型信息丢失"的组合:内层节点(Name / Attribute)的名字在 + `Gen.structs`(本模块已建)或 `Gen._struct_sha1_map`(预扫描的类→模块映射) + 中有类定义,而解析出的 `BaseType` 却是 `t.CVoid`。其余一律放行 + (`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 + Inner: ast.AST | None = None + if isinstance(Annotation, ast.Subscript) and IsPtrSubscriptNode(Annotation, self.Trans.SymbolTable): + Inner = Annotation.slice + elif isinstance(Annotation, ast.BinOp) and isinstance(Annotation.op, ast.BitOr): + for Side in FlattenUnionOperands(Annotation): + if not IsCPtrMarkerNode(Side, self.Trans.SymbolTable): + Inner = Side + break + if Inner is None: + return + InnerName: str | None = None + if isinstance(Inner, ast.Name): + InnerName = Inner.id + elif isinstance(Inner, ast.Attribute): + InnerName = Inner.attr + if not InnerName or InnerName in ('rawptr', 'CPtr'): + return + Gen: Any = getattr(self.Trans, 'LlvmGen', None) + if Gen is None: + return + if (InnerName not in getattr(Gen, 'structs', {}) + and InnerName not in getattr(Gen, '_struct_sha1_map', {})): + return + _e: Any = None + try: + _e = self.Trans.SymbolTable.lookup(InnerName) + except Exception: + _e = None + raise ValueError( + f"[FATAL] 成员 '{MemberName}' 的注解 '{AnnotationText}' 内层 '{InnerName}' " + f"是**已定义类**,却被解析成通用指针(类型信息丢失)—— 拒绝静默降级:" + f"解析结果 BaseType={Info.BaseType} PtrCount={getattr(Info, 'PtrCount', None)} " + f"IsStruct={getattr(Info, 'IsStruct', None)} IsTypedef={getattr(Info, 'IsTypedef', None)} " + f"Name={getattr(Info, 'Name', None)};" + f"符号表['{InnerName}'] => IsTypedef={getattr(_e, 'IsTypedef', None)} " + f"BaseType={getattr(_e, 'BaseType', None)} PtrCount={getattr(_e, 'PtrCount', None)} " + f"IsStruct={getattr(_e, 'IsStruct', None)} IsRenum={getattr(_e, 'IsRenum', None)} " + f"IsModuleAlias={getattr(_e, 'IsModuleAlias', None)} " + f"IsEnumMember={getattr(_e, 'IsEnumMember', None)};" + f"Gen.structs 命中={'有' if InnerName in getattr(Gen, 'structs', {}) else '无'} " + f"_struct_sha1_map 命中={getattr(Gen, '_struct_sha1_map', {}).get(InnerName)!r}" + ) + def LookupFunctionSymbol(self, name: str, *, module_path: str | None = None) -> CTypeInfo | None: """查找函数符号,先尝试 module_path.name,再回退到 name。