fix(attr): ALL_CAPS 非 CDefine 回退跨模块全局变量
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 形式)。
This commit is contained in:
1 parent
aa2a1e593f
commit
e8a3fd0a65
2 files changed
+35
-6
No files matched your search
@@ -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(
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user