fix(renum): 返回类型按结构体指针解析

REnum 预登记为 IsRenum/IsStruct;类型解析先判 REnum;_EmitREnumLlvm 复用已有结构体实例,修复 LLVMType* 退化为 i32*。
This commit is contained in:
TermiNexus committed 2026-10-18 21:17:03 +08:00
1 parent b6d6d5ac6b
commit fe10e4dcd2
3 files changed
+59 -9

No files matched your search

+15 -4
View File
@@ -1657,7 +1657,12 @@ class ClassHandle(BaseHandle):
# 预注册 REnum opaque 结构体到 Gen.structs 和 SymbolTable,
# 使自引用成员(如 CPtr[LLVMType] / rawptr[LLVMType])在收集成员时能正确解析为 %LLVMType*。
# 若不预注册,GetCTypeInfo 找不到 LLVMType → 回退到 IsEnum → i32 → 再加一层指针 → i32*(错误)。
PreRenumType: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, ClassName)
# 【类型身份唯一】必须复用 `_get_or_create_struct` 的实例:前向声明/导入 stub
# (_get_or_create_struct / _TryLoadStructFromStub)按 `_struct_sha1_map` 建出的
# 是 `%"{sha1}.<Class>"`;此处若无条件 new 一个 `%<Class>`,同一类在本模块内
# 出现两个 struct 实例 ⇒ 定义端返回 `%"{sha1}.T"*`、注解端 `%T*`,
# 触发"指针隐式转换已禁止(非基本类型(结构体/类/联合))"。
PreRenumType: ir.IdentifiedStructType = Gen._get_or_create_struct(ClassName)
Gen.structs[ClassName] = PreRenumType
PreTypeInfo: CTypeInfo = CTypeInfo()
PreTypeInfo.Name = ClassName
@@ -1759,13 +1764,19 @@ class ClassHandle(BaseHandle):
if not max_variant_struct:
max_variant_struct = [ir.IntType(32), ir.IntType(32)]
# 复用预注册的 opaque 结构体,设置 body 使其完整
PreRenumType.set_body(*max_variant_struct)
if PreRenumType.is_opaque:
PreRenumType.set_body(*max_variant_struct)
for VariantName, member_types, member_names, member_annotations, lineno, tag_value in variant_info:
NestedStructName: str = f"{ClassName}_{VariantName}"
if member_types:
padded_member_types: list[ir.Type] = list(max_variant_struct)
nested_struct_type: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, NestedStructName)
nested_struct_type.set_body(*padded_member_types)
# 变体嵌套结构体与主 REnum 同一条命名规则(`_get_or_create_struct`
# → `_struct_sha1_map` → `%"{sha1}.<REnum>_<Variant>"`),
# 否则导入端从 stub 拿到的是 sha1 前缀名,与定义端 `%<REnum>_<Variant>`
# 分裂成两个类型。
nested_struct_type: ir.IdentifiedStructType = Gen._get_or_create_struct(NestedStructName)
if nested_struct_type.is_opaque:
nested_struct_type.set_body(*padded_member_types)
Gen.structs[NestedStructName] = nested_struct_type
if NestedStructName not in Gen.class_members:
Gen.class_members[NestedStructName] = []