diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index 68b08d9..36c944e 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -784,6 +784,36 @@ class CallGenMixin(CallGenBase.CallGenBase): VpiReader._ensure_vpi_ret_annot_loaded(mod_ret_sha1, self.Gen.CallGenBase.TempDir) ret_annot_fc: str = VpiReader._lookup_vpi_ret_annot( mod_ret_sha1, None, func_name) + if ret_annot_fc is None: + # 包模块 vpi 未命中(函数定义在子模块,如 + # fltk.Fl_Input_value 实际在 fltk._cfl_input): + # 经 reexport 定位定义模块(star import 多候选 + # 逐个查返回注解)再查 vpi。 + rr_src: str = self.Gen.ImportsGen.lookup_reexport(mod_ret_sha1, func_name) + if rr_src is None: + rr_src = self._lookup_reexport_from_vpi(pool, mod_ret_sha1, func_name) + if rr_src is not None: + rr_total: t.CSizeT = string.strlen(rr_src) + rr_i: t.CSizeT = 0 + while rr_i < rr_total and ret_annot_fc is None: + while rr_i < rr_total and rr_src[rr_i] == ' ': + rr_i += 1 + if rr_i >= rr_total: + break + rr_start: t.CSizeT = rr_i + while rr_i < rr_total and rr_src[rr_i] != ' ': + rr_i += 1 + rr_len: t.CSizeT = rr_i - rr_start + rr_buf: str = pool.alloc(rr_len + 1) + if rr_buf is not None: + string.strncpy(rr_buf, rr_src + rr_start, rr_len) + rr_buf[rr_len] = '\0' + rr_sha1: str = self._lookup_module_sha1(rr_buf) + if rr_sha1 is not None: + VpiReader._ensure_vpi_ret_annot_loaded( + rr_sha1, self.Gen.CallGenBase.TempDir) + ret_annot_fc = VpiReader._lookup_vpi_ret_annot( + rr_sha1, None, func_name) if ret_annot_fc is not None: vpi_ret_ty = VpiReader._resolve_vpi_ret_annot_str( pool, ret_annot_fc, @@ -1209,11 +1239,20 @@ class CallGenMixin(CallGenBase.CallGenBase): rs_found = 1 break if rs_found == 0: - # 无验证通过(非 extern 函数):仍用首个候选作为 - # 定义模块(保持旧行为,普通跨模块函数带 sha1 前缀) - reexport_sha1: str = self._lookup_module_sha1(reexport_src) - if reexport_sha1 is not None: - mod_sha1 = reexport_sha1 + # star import 候选验证全部失败:func_name 可能定义在 + # 原模块自身(extern def 如 stdlib.malloc 定义在 stdlib, + # 而 stdlib 又 `from stdint import *` 产生误候选 stdint)。 + # 先验证原模块:extern/State → 裸名(rs_found=1 下方置裸名)。 + if self.Gen.CallGenBase.is_cexport_func(mod_sha1, func_name) != 0 or \ + self._is_state_func_from_vpi(pool, mod_sha1, func_name) != 0: + rs_found = 1 + call_name = func_name + else: + # 原模块未定义:回退首个候选(旧行为,普通跨模块 + # 函数带 sha1 前缀,如 ast._lexer_init 定义在 ast.lexer) + reexport_sha1: str = self._lookup_module_sha1(reexport_src) + if reexport_sha1 is not None: + mod_sha1 = reexport_sha1 # CExport 函数定义用裸名(@strlen),跨模块调用需用裸名而非 @{sha1}.func if rs_found != 0: pass # 已验证 reexport 定义模块并置裸名