fix(transpyv): ClassGenDef 用 c.DerefAs 物化 REnum 变体(替代 *ptr = <boxed 构造>)

c 源码违规:`*existing.Ty = llvmlite.LLVMType.Struct(...)` 把 **boxed 变体指针**
赋给了值槽(指针→值,严格规则禁止)。REnum 变体构造返回 boxed 指针,仓库既定
写法是用 c.DerefAs(ptr, <boxed 变体>) 做整对象物化(includes/llvmlite/__types.vp:195
的同款 `c.DerefAs(ptr, LLVMType.Struct(fields, fcount, name))`),
_HandleCDerefAsLlvm 的"整对象拷贝"分支正是为此(HandlesExprCall.py:4718-4740)。

用 DerefAs 而非改成 `existing.Ty = <新指针>`:本段的目的就是修 Phase 1a 遗留的
**悬空 Name**(注释 L97-101),Phase A 已把该指针登记进 named-type 表;换指针会让
旧条目继续指向悬空 Name,in-place 覆盖才保留指针同一性、真正修掉悬空。

现场报错:非基本类型的值/指针隐式转换已禁止(构造物化除外):
  不能把指针类型 %"50741ad4b4b0934d.LLVMType"* 隐式转为值类型
  %"50741ad4b4b0934d.LLVMType"
This commit is contained in:
TermiNexus committed 2026-09-28 23:15:46 +08:00
1 parent fddadf9d56
commit a9e4aafae1
1 file changed
+10 -1
+10 -1
View File
@@ -113,7 +113,16 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
on_copy: str = CompilerFactory.factory.PermPool.alloc(on_len + 1)
if on_copy is not None:
string.strcpy(on_copy, old_name)
*existing.Ty = llvmlite.LLVMType.Struct(llvmlite.get_struct_fields(existing.Ty), llvmlite.get_struct_fcount(existing.Ty), on_copy)
# in-place 覆盖所指 REnum 值(保留 existing.Ty 的指针同一性:
# Phase A 已把它登记进 named-type 表,换指针旧条目仍指向悬空
# Name)。REnum 变体构造返回 **boxed 指针**(见
# includes/llvmlite/__types.vp:185-196 的同款写法与
# __builder.vp:173 `result_ty: rawptr[LLVMType] =
# LLVMType.Ptr(ty)`),所以不能用 `*existing.Ty = <构造>`
# 直接赋值(指针→值,严格规则禁止);按仓库既定 idiom 用
# c.DerefAs(ptr, <boxed 变体>) 做**整对象物化**
# (HandlesExprCall._HandleCDerefAsLlvm 的"整对象拷贝"分支)。
c.DerefAs(existing.Ty, llvmlite.LLVMType.Struct(llvmlite.get_struct_fields(existing.Ty), llvmlite.get_struct_fcount(existing.Ty), on_copy))
# Phase B: 将已存在的命名结构体注册到当前模块(输出类型定义行)
llvmlite.module_add_named_type(trans.Module, pool, existing.Ty)
# B5:existing 路径(Phase B 已注册类)同样需设置 packed/aligned——