From b2fa70ae4bb3e6660c004fcb30a7edce2268a956 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 10 Aug 2026 01:46:37 +0800 Subject: [PATCH] =?UTF-8?q?fix(core):=20=E6=96=B9=E6=B3=95=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E5=8E=BB=E9=87=8D=20+=20=E8=B7=A8=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=A4=9A=E7=BB=A7=E6=89=BF=20MRO=20=E6=8C=89=E9=9C=80=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _HandleMethodCallLlvm fallback 创建函数前复用已有声明(vpi 合并) 避免 DuplicatedNameError;新增 _EnsureClassParentsLoaded 从 .vpi 按需加载 class_parents,使跨模块多继承类(如 Generator)的 MRO 回退能定位定义类(如 TypeGenMixin),修复 bootstrap 链接 undefined reference。 --- lib/core/Handles/HandlesExprCall.py | 37 +++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index a4991c5..9b4f422 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -920,6 +920,10 @@ class ExprCallHandle(BaseHandle): and ClassName not in Gen._cross_module_vtable_classes and class_sha1): self._try_register_vtable_ondemand(ClassName, class_sha1, Gen) + # 跨模块多继承:确保 class_parents 可用(MRO 回退需要)。 + # 如 HandlesType 委托调用 Generator 的方法——Generator 定义在 + # 另一模块,class_parents 未随 import 填充,需从 vpi 按需加载。 + self._EnsureClassParentsLoaded(ClassName, Gen) if (ClassName in Gen.class_vtable or ClassName in Gen._cross_module_vtable_classes) and ClassName in Gen.class_methods and CallArgs and not is_static_call: methods = Gen.class_methods[ClassName] if class_sha1: @@ -2404,6 +2408,28 @@ class ExprCallHandle(BaseHandle): return Gen.builder.bitcast(adj, ir.PointerType(Gen.structs[method_anc]), name=f"this_adjust_cast_{method_anc}") + def _EnsureClassParentsLoaded(self, ClassName: str, Gen: LlvmGeneratorMixin) -> None: + """跨模块多继承:class_parents 缺失时从 vpi 按需加载继承信息。 + + 调用方(如 HandlesType 委托)引用的类定义在另一模块,其父类 + 信息未随 import 填充。_TryLoadClassMembersFromPyi 读取 .vpi 中 + 的 ClassDef 并经 _EmitExternalClassDeclLlvm 填充 class_parents, + 使 _get_mro_chain 能沿 MRO 回退到定义类(如 TypeGenMixin)。 + """ + if not ClassName: + return + if Gen.class_parents.get(ClassName): + return + sha1_cls = Gen.ModuleSha1Map.get(ClassName) + if not sha1_cls: + sha1_cls = getattr(Gen, '_struct_sha1_map', {}).get(ClassName) + if not sha1_cls: + return + try: + self.Trans.ImportHandler._TryLoadClassMembersFromPyi(ClassName, f"{sha1_cls}.stub.ll", Gen) + except Exception: + pass + def _HandleMethodCallLlvm(self, Node: ast.Call) -> ir.Value: Gen = self.Trans.LlvmGen MethodName = Node.func.attr @@ -2862,6 +2888,9 @@ class ExprCallHandle(BaseHandle): and ClassName not in Gen._cross_module_vtable_classes and class_sha1): self._try_register_vtable_ondemand(ClassName, class_sha1, Gen) + # 跨模块多继承:确保 class_parents 可用(MRO 回退需要), + # 如 HandlesType 委托调用 Generator 的方法(定义类在 TypeGenMixin)。 + self._EnsureClassParentsLoaded(ClassName, Gen) if (ClassName in Gen.class_vtable or ClassName in Gen._cross_module_vtable_classes) and ClassName in Gen.class_methods: methods = Gen.class_methods[ClassName] @@ -3003,8 +3032,12 @@ class ExprCallHandle(BaseHandle): sig_params = [self_ptr_type] + sig_params param_types = sig_params func_type = ir.FunctionType(ret_type, param_types) - func = ir.Function(Gen.module, func_type, name=FullMethodName) - Gen.functions[FullMethodName] = func + # 复用已存在的声明(vpi 合并/LoadDepVpiIntoModule 可能已注册同名 declare), + # 避免 llvmlite DuplicatedNameError(如 gen.__init__ / ImportsHandle.HandleImport) + func = Gen._find_function(FullMethodName) + if func is None: + func = ir.Function(Gen.module, func_type, name=FullMethodName) + Gen.functions[FullMethodName] = func if isinstance(ObjVal.type, ir.PointerType) and ObjVal.type.pointee == struct_type: call_self = ObjVal else: