From 833e8c7c3344fa07af010d1ef66cf828d70e9dd1 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 28 Sep 2026 23:14:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpc):=20=E8=AF=86=E5=88=AB=E7=82=B9?= =?UTF-8?q?=E5=8F=B7=E5=86=99=E6=B3=95=E7=9A=84=20REnum=20=E5=8F=98?= =?UTF-8?q?=E4=BD=93=E6=9E=84=E9=80=A0=20mod.REnumClass.Variant(...)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit a 编译器缺陷(同一语义两种书写的判据不一致):HandlesExprCall 的跨模块 REnum 变体 构造分支只判 `isinstance(Node.func.value, ast.Name)`,即只认裸名写法 `LLVMType.Ptr(x)`;**点号写法** `llvmlite.LLVMType.Struct(fields, fcount, name)` (Node.func.value 是 Attribute)漏掉,落到下方"模块函数 Struct"路径 ⇒ · 返回类型被当成普通函数返回值(实为 boxed 变体构造指针); · 实参少一个 pool(arity 也不对)。 现场:ClassGenDef.vp:116 的 `*existing.Ty = llvmlite.LLVMType.Struct(...)` 报"不能把指针类型 %LLVMType* 隐式转为值类型 %LLVMType"。 补齐:新增同口径分支——Node.func.value 为 Attribute 时,按其 attr(REnum 类名) 在符号表(先试 f"{ModulePath}.{attr}" 再试裸名)取 IsRenum 条目,命中 RenumVariants 即走 _HandleREnumConstructLlvm(与裸名分支同一实现)。与 includes/llvmlite/__types.vp:195、__builder.vp:173 的既有用法一致。 --- lib/core/Handles/HandlesExprCall.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index e4fe8a3..b6cc9bb 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -910,6 +910,26 @@ class ExprCallHandle(BaseHandle): result = self._HandleREnumConstructLlvm(Node, RenumClassName, FuncAttr, TagValue) if result is not None: return result + # 跨模块 REnum 变体构造(**点号类名**写法):`mod.ClassName.Variant(args)` + # 现场:`llvmlite.LLVMType.Struct(fields, fcount, name)` —— Node.func.value + # 是 Attribute(llvmlite.LLVMType)而不是 Name,上一条判据(L903 的 + # isinstance(Node.func.value, ast.Name))漏掉 ⇒ 落到"模块函数 Struct"路径: + # 返回类型被当成普通函数返回值(实为 boxed 变体构造指针),且实参少一个 + # pool(arity 也不对)。此处与裸名写法同口径补齐,覆盖点号写法。 + if isinstance(Node.func.value, ast.Attribute): + _rc_attr: str = getattr(Node.func.value, 'attr', '') or '' + _rc_sym: Any = None + for _rc_key in (f"{ModulePath}.{_rc_attr}", _rc_attr): + if _rc_key and self.Trans.SymbolTable.has(_rc_key): + _rc_sym = self.Trans.SymbolTable[_rc_key] + break + if _rc_sym is not None and getattr(_rc_sym, 'IsRenum', False): + _rc_vars: Any = getattr(_rc_sym, 'RenumVariants', None) + if _rc_vars and FuncAttr in _rc_vars: + _rc_tag: int = _rc_vars.index(FuncAttr) + result = self._HandleREnumConstructLlvm(Node, _rc_attr, FuncAttr, _rc_tag) + if result is not None: + return result if self.Trans.SymbolTable.has(FuncAttr): SymInfo = self.Trans.SymbolTable[FuncAttr] if SymInfo.IsStruct: