diff --git a/lib/core/Handles/HandlesExprAttr.py b/lib/core/Handles/HandlesExprAttr.py index 2bec0c1..706d320 100644 --- a/lib/core/Handles/HandlesExprAttr.py +++ b/lib/core/Handles/HandlesExprAttr.py @@ -834,6 +834,18 @@ class ExprAttrHandle(BaseHandle): return cdefine_result ObjVal: Any = self.HandleExprLlvm(Node.value) if not ObjVal or not isinstance(ObjVal.type, ir.PointerType): + # 取证(纯记账):基座求值为空/非指针时,把**内层链的失败原因**一并挂上—— + # 嵌套读取的内层记录随后会被本节点的记录覆盖,报错点(本节点)与真因(内层某级) + # 相隔数层的可读性问题由此解决(现场:`GenApi._g_gen.TypeGenCType.CTypedefNames`)。 + _prev_an: Any = getattr(Gen, '_LastAttrNone', None) + _chain_an: str = '' + if (isinstance(_prev_an, tuple) and len(_prev_an) >= 3 and _prev_an[2] + and _prev_an[1] and _prev_an[1] != Node.attr): + _chain_an = f";内层字段 '{_prev_an[1]}' 的失败原因:{_prev_an[2]}" + self._NoteAttrNone( + Gen, None, Node.attr, + f"基座 {self._ExprShape(Node.value)} 求值为空或非指针" + f"(type={getattr(ObjVal, 'type', None)}){_chain_an}") return None pointee: Any = ObjVal.type.pointee @@ -887,25 +899,41 @@ class ExprAttrHandle(BaseHandle): or getattr(Gen, 'global_struct_class', {}).get(_mva.attr)) ResolvedKey: str | None = self._find_struct_key_for_class_hint(Gen, AttrClassName) if ResolvedKey is None or ResolvedKey not in Gen.structs: + self._NoteAttrNone( + Gen, AttrClassName, Node.attr, + f"基座字段的所属类未能在 Gen.structs 命中键(类名提示={AttrClassName!r}," + f"structs 键数={len(Gen.structs)})") return None st: Any ok: bool st, ok = self._try_Load_struct_from_stub(Gen, ResolvedKey) if not isinstance(st, ir.IdentifiedStructType): + self._NoteAttrNone(Gen, ResolvedKey, Node.attr, + f"类 '{ResolvedKey}' 的 struct 实例类型异常({type(st).__name__})") return None if st.elements is None: # stub 仍 opaque(如跨模块泛型仅声明):走泛型特化候选访问 spec_val: Any = self._try_access_opaque_generic_member(Gen, ObjVal, st, Node, ResolvedKey, AttrClassName) if spec_val is not None: return spec_val + self._NoteAttrNone( + Gen, ResolvedKey, Node.attr, + f"类 '{ResolvedKey}' 的 body 仍为 opaque(elements=None),且无泛型特化成员可访问") return None CastedObj: Any = Gen.builder.bitcast(ObjVal, ir.PointerType(st), name=f"cast_{ResolvedKey}") if Node.attr in Gen.class_member_bitoffsets.get(ResolvedKey, {}): return self._load_bitfield_member(CastedObj, ResolvedKey, Node.attr) offset: int | None = Gen._get_member_offset(Node.attr, ResolvedKey) if offset is None: + self._NoteAttrNone( + Gen, ResolvedKey, Node.attr, + f"字段 '{Node.attr}' 在类 '{ResolvedKey}' 中取不到偏移" + f"(成员表 {len(Gen.class_members.get(ResolvedKey) or [])} 项 / body {len(st.elements)} 槽)") return None if offset < len(st.elements) and isinstance(st.elements[offset], ir.VoidType): + self._NoteAttrNone( + Gen, ResolvedKey, Node.attr, + f"字段 '{Node.attr}' 的槽 {offset} 是 void(占位槽:类型信息缺失)") return None return self._gep_and_Load_member(Gen, CastedObj, offset, Node.attr, ResolvedKey, st) @@ -934,6 +962,11 @@ class ExprAttrHandle(BaseHandle): return self._load_bitfield_member(ObjVal, CN, Node.attr) offset = Gen._get_member_offset(Node.attr, CN) if offset is None: + self._NoteAttrNone( + Gen, CN, Node.attr, + f"字段 '{Node.attr}' 在类 '{CN}' 中取不到偏移" + f"(成员表 {len(Gen.class_members.get(CN) or [])} 项 / " + f"body {len(st.elements) if isinstance(st, ir.IdentifiedStructType) and st.elements is not None else 'opaque'} 槽)") break # 泛型基础类型字段特化(根本修复): # 当字段声明为特化泛型(如 GSList[BasicBlock])时,基础类型(GSList)的 @@ -965,6 +998,12 @@ class ExprAttrHandle(BaseHandle): return self._gep_and_Load_member(Gen, _casted, _off2, Node.attr, CN2, ST2) break return self._gep_and_Load_member(Gen, ObjVal, offset, Node.attr, CN, st) + # 结构体分支未命中任何类:pointee 与 Gen.structs 全部键都不等(同名类双实例 / + # 该类未注册)——这是"基座类型已知却读不到字段"的最后一种来源,必须留痕。 + self._NoteAttrNone( + Gen, None, Node.attr, + f"基座 pointee {pointee} 未匹配 Gen.structs 中任何 struct(键数={len(Gen.structs)})" + f";基座形态={self._ExprShape(Node.value)}") return None def _handle_attr_call_result(self, Node: ast.Attribute) -> ir.Value | None: