feat(overload): 跨模块调用 Mod.f(...) 接入重载决议

模块限定调用分支先按接收者路径解析目标模块 SHA1(含 from-import 别名),再以 prefix 模式在同名候选集里决议;vpi 注入的重载符号 {sha1}.f_v{hash} 与函数表项名 f_v{hash} 均能命中。单候选/非重载保持原 find_func_in_module 路径。至此模块级、实例方法、Class.m、静态方法、跨模块五条调用路径全部接入同一套 C++ 部分序决议。
This commit is contained in:
TermiNexus committed 2026-10-24 18:00:18 +08:00
1 parent f54c365b20
commit 850bad4e8a
1 file changed
+26 -1
+26 -1
View File
@@ -780,9 +780,34 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
if self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, bn_seg2) != 0: bn_seg2_mod = 1
if bn_seg2_cls != 0 or bn_seg2_mod == 0: found_func = None
else:
# 跨模块重载:先从接收者路径解析目标模块 SHA1,再在候选集里决议。
# vpi 注入的重载符号是 {sha1}.name_v{hash}、函数表项名带后缀,所以用 prefix 模式。
xm_sha1_ovl: str = None
if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute and trans is not None and trans._imported_modules is not None:
xm_at_ovl: ast.Attribute* = ast.Attribute*(cl.func)
xm_path_ovl: str = None
if xm_at_ovl is not None and xm_at_ovl.value is not None:
if xm_at_ovl.value.kind() == ast.ASTKind.Name:
xm_nm_ovl: ast.Name* = ast.Name*(xm_at_ovl.value)
if xm_nm_ovl.id is not None: xm_path_ovl = xm_nm_ovl.id
elif xm_at_ovl.value.kind() == ast.ASTKind.Attribute:
xm_path_ovl = self.Gen.ExprGenAttr._attr_module_path_str(pool, xm_at_ovl.value)
if xm_path_ovl is not None:
if self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, xm_path_ovl) != 0:
xm_sha1_ovl = self._lookup_module_sha1(xm_path_ovl)
if xm_sha1_ovl is None and trans._from_imports is not None:
xm_sha1_ovl = self.Gen.StructGen._resolve_module_sha1(xm_path_ovl, trans._from_imports)
found_func: mlirlite.Function* = None
ovl_done_rm: int = 0
if xm_sha1_ovl is not None and trans._funcs is not None:
if self.Gen.CallGenLeafKit.count_owned_overloads(trans._funcs, trans._func_count, func_name, xm_sha1_ovl, 1) >= 2:
rm_f: mlirlite.Function* = self.Gen.CallGenLeafKit.resolve_overload_call(pool, trans, trans._funcs, trans._func_count, func_name, xm_sha1_ovl, cargs, can, cl.func, 1, 0)
if rm_f is None: return mlirlite.const_int32(pool, 0)
found_func = rm_f
ovl_done_rm = 1
# Module-qualified/attribute call: exact match first; suffix match accepts only module
# functions. Reject suffix hits that are methods (SHA1.Class.method), keeping SHA1.func / SHA1.submod.func.
found_func = self.find_func_in_module(mod, func_name)
if ovl_done_rm == 0: found_func = self.find_func_in_module(mod, func_name)
if found_func is not None:
# Module-qualified call (mod.func): require found_func's SHA1 prefix to equal that module,
# else the stub suffix match may hit another module's same-name function (wrong symbol/crash).