diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 1bfa96a..175a76a 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -2628,6 +2628,12 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModul if existing_c is not None and existing_c.Ty is not None: if existing_c.IsForwardDecl != 0: fill_fwd_c = 1 else: + # entry 已在全局 StructTable(可能由别的模块先注入/注册),但**本模块**的 NamedTypeHead + # 不保证有它的完整定义:只有被按值使用(值返回类型 / 值字段 / 数组元素)时打印才回查登记 + # 表,而指针引用只会登记 opaque 前向声明 → 打印签名/类型时报 "still opaque"。故这里补齐 + # 本模块的完整定义(幂等:add_named_type 同名去重,完整定义替换 opaque)。 + mlirlite.module_add_named_type(mod, pool, existing_c.Ty) + if existing_c.IsPacked != 0: mlirlite.module_set_named_type_packed(mod, pool, existing_c.Ty, 1) GenApi.add_visible_struct(pool, real_name) return 1 # Skip REnum classes (class X(t.REnum)): their layout is computed from variants by @@ -3112,6 +3118,11 @@ def _inject_method_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, m_ if ret_ty is None and string.strcmp(m_fd.name, "__init__") == 0: ret_ty = mlirlite.Void(pool) if ret_ty is None: ret_ty = i32_ty + # 跨模块方法**按值返回类**时,引用模块必须登记该具名结构体的完整定义:否则打印方法签名回查登记表, + # 命中的只是指针引用登记的 opaque 前向声明 → MLIR 报 "still opaque at print time"。与 + # _inject_function_declare 同口径(那里对值返回类型调 _ensure_full_value_types)。 + _ensure_full_value_types(mod, pool, ret_ty) + # create the declare func: mlirlite.Function* = mlirlite.create_declare(pool, mod, mangled_name, ret_ty) if func is None: return