From e8a3fd0a6551ef3d3bb092a7a46870a3c36b4234 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 19 Aug 2026 05:41:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(attr):=20ALL=5FCAPS=20=E9=9D=9E=20CDefine?= =?UTF-8?q?=20=E5=9B=9E=E9=80=80=E8=B7=A8=E6=A8=A1=E5=9D=97=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase1.PYI_BUF_SIZE: t.CSizeT = 262144 是 i64 模块级全局而非 CDefine 宏, 语义同 C 的 extern size_t PYI_BUF_SIZE。原 ALL_CAPS 属性路径在 CDefine 查找失败后直接 fail-fast,从不尝试跨模块全局。修复: - ExprGenAttr 模块限定路径:CDefine 失败时先查 find_global_in_module, 命中则按跨模块全局引用加载,仅全局也不存在时才 fail-fast; - ExprGenName 裸名路径:from-import 确认后同样回退跨模块全局加载 (覆盖 from Phase1 import PYI_BUF_SIZE 形式)。 --- App/lib/core/Gen/ExprGenAttr.vp | 17 +++++++++++------ App/lib/core/Gen/ExprGenName.vp | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/App/lib/core/Gen/ExprGenAttr.vp b/App/lib/core/Gen/ExprGenAttr.vp index b5b025b..6d7834f 100644 --- a/App/lib/core/Gen/ExprGenAttr.vp +++ b/App/lib/core/Gen/ExprGenAttr.vp @@ -564,13 +564,18 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 此处返回 None,让上层嵌套属性访问路径处理 if string.strcmp(nm_ma.id, "t") == 0 and string.strcmp(at.attr, "ASM_DESCR") == 0: return None - # CDefine 未找到且属性名符合 ALL_CAPS 约定: fail-fast 终止编译 - # 不再创建未定义的外部全局变量引用(否则 llc 报 "use of undefined value") + # ALL_CAPS 模块属性但非 CDefine:先检查模块是否定义了同名全局 + # 变量(如 Phase1.PYI_BUF_SIZE: t.CSizeT = 262144 是 i64 全局、 + # 非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)→ 按跨模块全局 + # 引用加载。仅当全局变量也不存在时才 fail-fast(防 llc + # "use of undefined value")。 if HandlesExpr._is_cdefine_name_pattern(at.attr) != 0: - HandlesType.fatal_error( - at, - f"跨模块 CDefine 未找到: '{nm_ma.id}.{at.attr}'(CDefine cross-module lookup failed)", - "TypeError") + if self.find_global_in_module(mod, at.attr) is None: + HandlesType.fatal_error( + at, + f"跨模块 CDefine 未找到: '{nm_ma.id}.{at.attr}'(CDefine cross-module lookup failed)", + "TypeError") + # 命中跨模块全局 → 落到下方跨模块全局加载路径 # 非 CDefine: 使用 i8* 作为类型提示 (模块级变量通常存储指针) i8_ptr_hint: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, llvmlite.Int8(pool)) mod_gv_ref: llvmlite.Value | t.CPtr = self._resolve_module_attribute_global( diff --git a/App/lib/core/Gen/ExprGenName.vp b/App/lib/core/Gen/ExprGenName.vp index 0aadd15..e9a01d4 100644 --- a/App/lib/core/Gen/ExprGenName.vp +++ b/App/lib/core/Gen/ExprGenName.vp @@ -99,6 +99,30 @@ class ExprGenName(ExprGenBase.ExprGenBase): return llvmlite.ConstFloat(pool, llvmlite.Double(pool), dchk_nm) return HandlesExpr._const_int_for_cdefine(pool, cdef_val) + # CDefine 查找失败:from-import 的模块级全局变量(如 + # from Phase1 import PYI_BUF_SIZE;PYI_BUF_SIZE: t.CSizeT = 262144 是 + # i64 全局、非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)。from-import + # 确认名称确实来自某模块后,按后缀匹配查找该全局并加载。 + if trans is not None and trans._from_imports is not None: + fi_mod_raw: str = HandlesImports.lookup_from_import( + trans._from_imports, nm_id, 0) + if fi_mod_raw is not None: + fi_gv: llvmlite.GlobalVariable | t.CPtr = HandlesExpr.find_global_in_module( + trans.Module, nm_id) + if fi_gv is not None and fi_gv.Ty is not None: + fi_ref: llvmlite.Value | t.CPtr = HandlesExpr.make_global_ref( + pool, nm_id, fi_gv.Ty) + if fi_ref is not None and fi_ref.Ty is not None: + fi_pty: llvmlite.LLVMType | t.CPtr = fi_ref.Ty.Pointee + if fi_pty is not None: + match fi_pty: + case llvmlite.LLVMType.Array(_, _): + # 数组全局按 C 语义退化为基址(对齐 L3383-3388) + return fi_ref + case _: + pass + return llvmlite.build_load(builder, fi_pty, fi_ref) + # global 变量:从模块作用域查找(global 声明优先级最高) if trans is not None: if HT.is_global_name(trans, nm_id) != 0: