fix(tpv): lookup_field_by_class 模块限定路径补 REnum 变体字段别名回退

llvmlite.LLVMType.Pointee 等模块限定 REnum 字段访问:类命中(FieldCount=4)但变体字段名(_p1/_p2 槽位别名)不是普通字段,此前变体别名回退只在裸名路径,模块限定路径 fatal 先触发永远走不到(CallGenDispatch L1005 根因)。在模块限定路径字段未找到时补 _lookup_renum_field_alias 回退,与裸名路径一致。同时移除已定位完成的 REEXPORT-DBG 临时诊断。
This commit is contained in:
TermiNexus committed 2026-08-29 10:03:10 +08:00
1 parent 9af7b2ead4
commit 8d0241e0c3
2 files changed
+27 -36

No files matched your search

-23
View File
@@ -1361,26 +1361,10 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
stub_from_imports = _stub_add_from(
pool, stub_from_imports, slocal, sifr_mod, sorig)
# 重导出类以包 sha1 注册(asname 时按别名注册)
# [REEXPORT-DBG] 临时诊断:ast.Attribute 未注册根因定位
# (AssignGenMixin.vp L46 lookup_field_by_class fail-fast)。
if is_pkg_init_rt != 0 and sub_sha1_rt is not None:
_inject_reexport_class_declare(
pool, mod, sial.name, slocal,
sub_sha1_rt, src_sha1)
elif string.strcmp(sial.name, "Attribute") == 0 \
or string.strcmp(sial.name, "AST") == 0:
rel_p_dbg: str = "?"
if src_sha1 is not None:
rel_p_dbg = StubMergerStore.LookupSha1RelPath(src_sha1)
sub_s_dbg: str = "?"
if sub_sha1_rt is not None:
sub_s_dbg = sub_sha1_rt
src_s_dbg: str = "?"
if src_sha1 is not None:
src_s_dbg = src_sha1
stdio.printf("[REEXPORT-DBG] 跳过重导出: name=%s mod=%s is_pkg=%d sub_sha1=%s src_sha1=%s rel=%s\n",
sial.name, sifr_mod, is_pkg_init_rt,
sub_s_dbg, src_s_dbg, rel_p_dbg)
# 用 stub 自己的 imports 替代当前模块的(stub 注解解析上下文正确性)
imported_modules: str = trans._imported_modules
@@ -1586,16 +1570,9 @@ def _inject_reexport_class_declare(pool: memhub.MemBuddy | t.CPtr,
# 找子模块源 entry(仅类有 entry;函数/常量查不到自然跳过)
src_entry: GenTypes.StructEntry | t.CPtr = GenApi.find_struct_by_module(src_name, sub_sha1)
if src_entry is None or src_entry.Ty is None:
# [REEXPORT-DBG] 临时诊断:子模块类未注册(重导出前置依赖缺失)
# ast.Attribute 根因候选 1:ast.exprs.Attribute(sub_sha1)未注册。
stdio.printf("[REEXPORT-DBG] src_entry=None: name=%s sub_sha1=%s pkg_sha1=%s\n",
src_name, sub_sha1, pkg_sha1)
return 0
# 注册别名 entry(绕过 register_struct 的 Ty 去重)
if GenApi.register_struct_alias(pool, local_name, pkg_sha1, src_entry) is None:
# [REEXPORT-DBG] 临时诊断:别名注册失败(STRUCT_MAX 上限或分配失败)
stdio.printf("[REEXPORT-DBG] register_struct_alias=None: name=%s pkg_sha1=%s src_sha1=%s\n",
local_name, pkg_sha1, sub_sha1)
return 0
GenApi.add_visible_struct(pool, local_name)
return 1
+27 -13
View File
@@ -885,25 +885,39 @@ class StructGenMixin:
if string.strcmp(fe_q.Name, field_name) == 0:
stdlib.free(mod_buf_q)
return fe_q
# REnum 变体字段别名回退(与裸名路径 L950-963 一致):
# 模块限定访问(llvmlite.LLVMType.Pointee)类命中后字段
# 未找到时,直接查变体别名(REnum 字段是 _p1/_p2 槽位,
# Pointee 是 Ptr 变体成员)。此前该回退只在裸名路径,
# 模块限定路径此处 fatal 先触发 → 永远走不到
# (CallGenDispatch.vp L1005 rk_pointee.Pointee 根因)。
rn_cls_q: str = mod_entry_q.Name
if rn_cls_q is None:
rn_cls_q = bare_q
rn_is_renum_q: int = \
self.Gen.ClassGenEnum._is_renum_class_name(bare_q)
if rn_is_renum_q == 0 and rn_cls_q is not None:
rn_is_renum_q = \
self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_q)
rn_alias_q: int = -1
if rn_is_renum_q != 0:
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(
rn_cls_q, field_name)
if rn_alias_q < 1 and bare_q is not rn_cls_q:
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(
bare_q, field_name)
if rn_alias_q >= 1:
rn_fe_q: GenTypes.FieldEntry | t.CPtr = \
self._get_field_entry(mod_entry_q, rn_alias_q)
if rn_fe_q is not None and rn_fe_q.Ty is not None:
stdlib.free(mod_buf_q)
return rn_fe_q
# 类命中但字段未找到:可读化报错(traceback 格式)
self.Gen.TypeGenErr.fatal_error(node, f"lookup_field_by_class: 类 '{class_name}' 已按模块归属解析(ModuleSha1={mod_sha1_q}, FieldCount={mod_entry_q.FieldCount})但字段 '{field_name}' 未找到", "AttributeError")
stdlib.free(mod_buf_q)
return None
# 模块可解析但类未注册:fail-fast(暴露 vpi 注入/注册缺陷,
# 不再裸名跨库抓其他模块同名类)
# [REEXPORT-DBG] 临时诊断:区分"裸名未注册"与"注册在其它 sha1"
dbg_cnt_bare: int = 0
dbg_i_bare: int
for dbg_i_bare in range(self.StructCount):
dbg_ent_b: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(dbg_i_bare)
if dbg_ent_b is not None and dbg_ent_b.Name is not None:
if string.strcmp(dbg_ent_b.Name, bare_q) == 0:
dbg_cnt_bare += 1
if dbg_cnt_bare <= 3 and dbg_ent_b.ModuleSha1 is not None:
stdio.printf("[REEXPORT-DBG] 裸名 '%s' 已注册: sha1=%s FC=%d\n",
bare_q, dbg_ent_b.ModuleSha1, dbg_ent_b.FieldCount)
stdio.printf("[REEXPORT-DBG] 类 '%s' 未注册: mod=%s mod_sha1=%s 裸名同名注册数=%d\n",
bare_q, mod_buf_q, mod_sha1_q, dbg_cnt_bare)
self.Gen.TypeGenErr.fatal_error(node, f"lookup_field_by_class: 类 '{class_name}' 未找到(模块 '{mod_buf_q}' 可解析 sha1={mod_sha1_q},但无同名注册类;请检查 vpi stub 注入或编译顺序)", "AttributeError")
stdlib.free(mod_buf_q)
return None