fix(tpc): stub 加载器解析全局变量声明——跨模块全局变量不再静默丢失

- 根因:_LoadDeclarationsFromStubLlvm 只解析 struct/declare,忽略全局变量声明行,TPC 编译 TPV 时跨模块全局变量(StubMerger._sha1_store_count 等)从未嵌入 Gen.module.globals
- 后果:_lookup_module_global 恒 None -> return 静默跳过 ret(HandlesReturn 的 if Val 分支)、跨模块赋值静默丢失
- 修复:逐行循环加分支解析 16hex 前缀的 external global 声明(剥离 zeroinitializer 与 align 尾部修饰),用 _parse_llvm_type 解析类型后嵌入 external GlobalVariable;.str. 内部常量与 @main 等非 16hex 前缀跳过
- 诊断脚本验证 4 种真实 stub.ll 格式(struct 指针/数组/zeroinitializer/vtable 结构体)全部解析成功
This commit is contained in:
TermiNexus committed 2026-08-22 04:21:04 +08:00
1 parent 4b0482657b
commit 56a4b5c818
1 file changed
+21 -1
+21 -1
View File
@@ -2681,7 +2681,27 @@ class ImportHandle(BaseHandle):
raise
_vlog().warning(f"处理导入失败: {_e}", "Exception")
continue
# 全局变量声明:@sha1.name = external global TYPE(stub.ll 写入,
# 原加载器只解析 struct/declare、忽略全局变量 → TPC 编译 TPV 时
# 跨模块全局变量(如 StubMerger._sha1_store_count)从未嵌入
# Gen.module.globals → _lookup_module_global 恒 None → return
# 静默跳过 ret / 跨模块赋值丢失。此处嵌入 external 声明,
# 名称格式与定义一致(@{sha1}.{name},temp/*.text.ll 确认)。
_gv_match = re.match(r'@("?)([a-f0-9]{16}\.[\w.\[\]]+)\1\s*=\s*external\s+global\s+(\S.*)', stripped)
if _gv_match:
_gv_name: str = _gv_match.group(2)
_gv_type_str: str = _gv_match.group(3).strip()
# 去掉尾部修饰(zeroinitializer / , align N),只保留类型
_gv_type_str = re.sub(r'\s+zeroinitializer.*$', '', _gv_type_str)
_gv_type_str = re.sub(r'\s*,\s*align\s+\d+.*$', '', _gv_type_str)
if _gv_name not in Gen.module.globals:
_gv_ty: ir.Type | None = self._parse_llvm_type(_gv_type_str, Gen, source_sha1=source_sha1)
if _gv_ty is not None:
_gv = ir.GlobalVariable(Gen.module, _gv_ty, name=_gv_name)
_gv.linkage = 'external'
continue
if not stripped.startswith('declare '):
continue