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: