From 2bfcb6ef6e50b385ae51ca396240c615a7bb4d24 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 1 Oct 2026 13:57:04 +0800 Subject: [PATCH] =?UTF-8?q?fix(TPV):=20=E4=BF=AE=20455c760=20=E9=81=97?= =?UTF-8?q?=E6=BC=8F=E2=80=94=E2=80=94args=5Fnode=20=E5=BF=85=E9=A1=BB?= =?UTF-8?q?=E5=A3=B0=E6=98=8E=E5=9C=A8=20decl=5Freuse=20=E5=88=86=E6=94=AF?= =?UTF-8?q?=E4=B9=8B=E5=A4=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现场:Test/FakeDuckTest 编译 includes/viperio.vp 第 12 行 self.data = data → NameError: 未定义名称 'data' (Buf.__init__ 的第一个形参名在方法体里找不到。) 原因:455c760 把整段"参数创建块"置于 if decl_reuse == 0: 之下时,把 args_node: ast.Arguments* = fd.args 一并圈了进去;但函数体段的 "为其他参数创建 alloca 并 store"(ClassGenVTable.vp:904 起)仍要遍历 args_node。复用前向声明(decl_reuse==1,现已是常规路径)时 args_node 未定义 → 形参不进符号表 → 方法体引用形参名即报 NameError。 修法:把 args_node 的声明提到 decl_reuse 分支之前。该块内其余变量 (md_defaults/md_default_count/md_param_count/md_args_node/md_ags/ md_alist/md_dlist/max_funcs/first_pname/first_pname_buf/fd_ags/ fd_first_arg/ags/alist/an/start_idx/ai/arg/param_ty/resolved/pname/ i1_ty_si/i1_ptr_ty_si)已逐一核对,全部只在块内使用,无需外提。 待验证:重编译 TransPyV(自举两遍)→ FileIoTest / FakeDuckTest。 --- App/lib/core/Gen/Class/ClassGenVTable.vp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index dfb43d2..dd91c57 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -704,6 +704,11 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # declare、函数体整体丢失(对齐 FuncGenDef.vp:544-545)。 func.IsDeclared = 0 + # 形参表:下方"函数体段"(形参建 alloca + 登记符号)与参数创建块都要用, + # 必须声明在 decl_reuse 分支之外——复用前向声明时不再走参数创建块, + # 但函数体段仍要遍历形参,否则实参名不进符号表(NameError: 未定义名称)。 + args_node: ast.Arguments* = fd.args + if decl_reuse == 0: # 提取默认参数信息(普通方法 args[0] 是 self,不含在 param_count 中; # @staticmethod 无 self,param_count 为完整参数数) @@ -749,7 +754,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): llvmlite.add_param(pool, func, self_ptr_ty, first_pname_buf) # 添加其他参数(支持类型注解;@staticmethod 从索引 0 开始,其余跳过索引 0 的 self/cls) - args_node: ast.Arguments* = fd.args + # args_node 已在 decl_reuse 分支之外声明(函数体段同样要用) if args_node is not None: ags: ast.Arguments* = ast.Arguments*(args_node) if ags.args is not None: