diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 6d99a37..d24b1d3 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -439,6 +439,32 @@ class TranslatorGenMixin: str_len + 1, str_len + 1, str_name_buf) return init_buf + def _stg_field_zero_text(self, pool: memhub.MemBuddy | t.CPtr, + fty: llvmlite.LLVMType | t.CPtr, + ty_str: str) -> str: + """按 LLVM 类型生成 storage struct 字段的零值初始化器文本 + + LLVM struct 初始化器必须列全所有字段(部分初始化 llc 报 + "initializer with struct type has wrong # elements")。 + Ptr→null、Int→0、Float→0.0、Array/Struct→zeroinitializer。 + """ + if fty is None or ty_str is None: + return None + buf: str = pool.alloc(160) + if buf is None: + return None + match fty: + case llvmlite.LLVMType.Ptr(_): + viperlib.snprintf(buf, 160, "%s null", ty_str) + case llvmlite.LLVMType.Int(_): + viperlib.snprintf(buf, 160, "%s 0", ty_str) + case llvmlite.LLVMType.Float(_): + viperlib.snprintf(buf, 160, "%s 0.0", ty_str) + case _: + # Array / Struct 等 aggregate → zeroinitializer + viperlib.snprintf(buf, 160, "%s zeroinitializer", ty_str) + return buf + # ============================================================ # handle_module_level_var - 模块级变量声明 → 创建 LLVM 全局变量 # @@ -682,14 +708,35 @@ class TranslatorGenMixin: viperlib.snprintf(vt_name_buf, 128, "%s.vtable", resolved_stg_entry.Name) vt_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vt_name_buf) if vt_mangled is not None: - vt_init_len: t.CSizeT = t.CSizeT(string.strlen(vt_mangled)) + 32 - vt_init_buf: str = pool.alloc(vt_init_len) - if vt_init_buf is not None: + # 完整 struct 初始化器(LLVM 拒绝部分初始化): + # 字段 0 = __vtable__(i8* @vtable),其余用户字段按类型零值。 + init_full_len: t.CSizeT = 16384 + init_full: str = pool.alloc(init_full_len) + if init_full is not None: + written_v: t.CInt = viperlib.snprintf(init_full, init_full_len, "{ ") + pos_v: t.CSizeT = t.CSizeT(written_v) if self.Gen.ClassGenVTable._vtable_name_needs_quote(vt_mangled) != 0: - viperlib.snprintf(vt_init_buf, vt_init_len, "{ i8* @\"%s\" }", vt_mangled) + written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, "i8* @\"%s\"", vt_mangled) else: - viperlib.snprintf(vt_init_buf, vt_init_len, "{ i8* @%s }", vt_mangled) - stg_init_text = vt_init_buf + written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, "i8* @%s", vt_mangled) + pos_v += t.CSizeT(written_v) + fc_v: int = resolved_stg_entry.FieldCount + for fi_v in range(1, fc_v): + fe_v: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry( + resolved_stg_entry, fi_v) + if fe_v is None or fe_v.Ty is None: + continue + ty_buf_v: str = pool.alloc(128) + if ty_buf_v is None: + continue + llvmlite.TypePrint(ty_buf_v, 128, fe_v.Ty, pool) + zero_v: str = self._stg_field_zero_text(pool, fe_v.Ty, ty_buf_v) + if zero_v is None: + continue + written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", zero_v) + pos_v += t.CSizeT(written_v) + viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, " }") + stg_init_text = init_full stg_name_len: t.CSizeT = t.CSizeT(string.strlen(mangled_name)) + 8 stg_name_buf: str = pool.alloc(stg_name_len) if stg_name_buf is not None: