fix(classdef): 已注册类早退路径补字段类型完整定义

上一条(96dad30)只改了"全新定义"路径的字段扫描循环,但 includes 在 Phase A 预注册、Phase B 重新翻译时走的是 existing 早退分支(ClassGenDef 117-167,只 module_add_named_type 后即 return 0),字段循环根本不执行 ⇒ includes/condition.vp 的 Condition 仍内嵌 opaque 成员、自身 unsized,llc 仍报 base element of getelementptr must be sized。

物证:同一构建里 ThreadingTest 的 main.vp(fb785af4a2aa1a46.ll)因按需调 ensure_struct_def_in_module,已正确拷入 CRITICAL_SECTION/CONDITION_VARIABLE/SRWLOCK 的完整定义;而定义它们的 condition.vp 自身(de351f55b29d33a3.ll)没有 ⇒ 只有定义模块自身体内 GEP 时才暴露。

修复:早退分支在 module_add_named_type 后补调 _ensure_field_types_in_module(Struct/Array 值类型递归补完整定义、Ptr 补 opaque),与全新定义路径同口径。
This commit is contained in:
TermiNexus committed 2026-10-03 16:05:24 +08:00
1 parent 96dad309ac
commit da18dd39a4
1 file changed
+10
+10
View File
@@ -154,6 +154,16 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
# 必须补设 IsPacked——否则跨模块 stub 注入(ensure_struct_def
# _in_module)按 entry.IsPacked 判定 packed 时读 0 → stub 非 packed。
existing.IsPacked = 1
# 字段类型补齐(与下方"全新定义"路径同口径):值类型字段(结构体本体 /
# 结构体数组)必须在当前模块有**完整定义**,只给 opaque 会让本类 unsized
# ⇒ 本模块内对本类做带字段下标的 GEP 时 llc 报
# "base element of getelementptr must be sized"(现场:includes/
# condition.vp 的 Condition{cond_var: CONDITION_VARIABLE,
# cs: CRITICAL_SECTION},后两者定义在 w32/win32sync.vp,新近由
# `t.CTypedef = VOIDPTR` 改成 class)。指针字段只需 opaque 声明。
# 本条路径是 includes 在 Phase A 预注册、Phase B 重新翻译时走的
# 早退分支(不经过下方全新定义路径的字段扫描循环)。
self.Gen.StructGen._ensure_field_types_in_module(pool, trans.Module, existing.Ty)
align_ex: int = self.Gen.ClassGenBase._class_aligned_value(cd.decorator_list)
if align_ex > 0 and existing.Align == 0:
existing.Align = align_ex