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: