diff --git a/App/lib/core/Gen/Class/ClassGenDef.vp b/App/lib/core/Gen/Class/ClassGenDef.vp index 1739d3d..dc97add 100644 --- a/App/lib/core/Gen/Class/ClassGenDef.vp +++ b/App/lib/core/Gen/Class/ClassGenDef.vp @@ -577,14 +577,27 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): if is_packed_cd != 0: llvmlite.module_set_named_type_packed(trans.Module, pool, struct_ty, 1) - # 扫描字段类型,为跨模块结构体引用添加 opaque 声明 + # 扫描字段类型:跨模块结构体引用在当前模块补声明 # 例如 list[int].__pool__ 引用 memhub.MemManager,需要在当前模块添加 %"sha1.MemManager" = type opaque for fi in range(field_count): fty_addr_op: sizet = field_types_buf[fi] if fty_addr_op == 0: continue fty_op: llvmlite.LLVMType* = (llvmlite.LLVMType*)(fty_addr_op) - llvmlite.module_ensure_opaque_for_type(trans.Module, pool, fty_op) + if self.Gen.ExprGenBase.is_ptr_type(fty_op) != 0: + # 指针字段:指向物只需 opaque 声明(GEP 不按字段下标解引用指向物本体) + llvmlite.module_ensure_opaque_for_type(trans.Module, pool, fty_op) + else: + # 值类型字段(结构体本体 / 结构体数组):必须复制**完整定义**。只给 + # opaque 会让**本类**变成 unsized(LLVM:含 unsized 成员的结构体自身 + # 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(指针层级收紧后 c.Addr 需要一层指针)。 + # _ensure_field_types_in_module 负责数组元素结构体的完整定义。 + self.Gen.StructGen.ensure_struct_def_in_module(pool, trans.Module, fty_op) + self.Gen.StructGen._ensure_field_types_in_module(pool, trans.Module, fty_op) # ============================================================ # 3. 注册到 HandlesStruct