diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index f617f74..5dca602 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -1624,6 +1624,12 @@ class AssignHandle(BaseHandle): Lines.append( f" class_members[{ClassName}] 项数={len(Members)} base={Base} " f"下标={Idx} 声明槽类型={Declared}") + # 名序(index:name):偏移=下标法/配对法算错时,第一现场就是"名序与 body + # 布局不同源"(如把某字段排到表尾/表头)。逐项列出即可直接与 body 槽对照, + # 不必再猜是哪一侧漂移(现场:TypeGenMixin 41 项里 'Gen' 本应在 0)。 + Lines.append(" class_members 名序: [" + + ", ".join(f"{_mi}:{_mn}" for _mi, (_mn, _) in enumerate(Members)) + + "]") except Exception as _e1: Lines.append(f" class_members 读取失败: {type(_e1).__name__}: {_e1}") Layout: Any = None diff --git a/lib/core/LLVMCG/FuncGen.py b/lib/core/LLVMCG/FuncGen.py index 95cf436..1d6c502 100644 --- a/lib/core/LLVMCG/FuncGen.py +++ b/lib/core/LLVMCG/FuncGen.py @@ -453,8 +453,20 @@ class FuncGenMixin: # 校准办法:对 b∈{0,1,2} 逐项比较"成员声明类型 vs elements[b+i] 类型", # 取一致度最高者(完全相同 +2;同为指针但类型不同 +0)。正确对齐时 # 指针槽几乎全中,错位对齐只能靠 i32 撞运气,分数明显更低;平手保留启发式。 + # + # 【只在长度不齐(_Delta != 0)时校准】_Delta == 0 表示"成员表项数 == body + # 槽数":定义端 body 由成员表生成、跨模块端 body(.stub.ll)与 .vpi 同源 + # (同一声明顺序),长度相等即**逐位对齐**,base 必为 0。此时再用严格类型 + # 比较挑 b 反而会误判——声明侧的联合类型(如 `list[str] | t.CPtr`)可能被记成 + # 折叠后的 i8*,而 body 槽仍是具体指针(`%list[str]*`):b=0 丢掉这些匹配, + # 某个平移 b 却能靠指针槽互相撞分拿到更高分。 + # 现场(2026-09-30):TypeGenMixin(41 成员 / 41 槽 / @t.NoVTable,_Delta=0) + # base 被抬到 2 ⇒ `SubTypeGen.Gen = self`(Gen 声明 Generator*、正确槽 0) + # 落到槽 40(TypeSpecArena*)⇒ "指针隐式转换已禁止(非基本类型(结构体/类/联合))"。 + # _Delta != 0 的既有现场(ast.Constant 的 `cnst.lineno` 落到 pool 槽等)不受影响, + # 仍走校准。 _MembersCal: list = self.class_members.get(_Cls, []) - if _MembersCal and _NumElems > 0: + if _MembersCal and _NumElems > 0 and _Delta != 0: _BestB: int = base _BestScore: int = -1 _HeurScore: int = -1