fix(stub): declare 侧识别 t.CPtr[...] 段,与定义侧指针层级口径对齐
t.CUInt8T | t.CPtr[t.CPtr] 在定义侧(TypeGenResolve._is_cptr_subscript)按指针层级合并得 i8**,但声明侧段判据只认整段等于 t.CPtr/CPtr,下标段落入普通段解析后取首段 => i8,造成跨模块 define/declare 签名不一致(实参 1 字节 vs 写入 8 字节) 新增 t.CPtr[/c.CPtr[ 段的识别与递归解析(与同文件 rowptr[...] 分支同构),数外层 Ptr 层数 N 后按 Ptr^N 合并;裸 t.CPtr 段路径未动,未放宽 fail-fast 注: TPC 侧 LLVMTypeMapper._resolve_bitor 与 SymbolUtils.IsCPtrNode 同源缺陷未改,两套编译器需同时修以免产物分叉
This commit is contained in:
1 parent
de86a1ed70
commit
31b8dccffd
1 file changed
+81
-1
@@ -1198,6 +1198,31 @@ def _resolve_single_vpi_type_str(pool: rowptr[memhub.MemBuddy],
|
||||
if inner_ty_rp is not None:
|
||||
return llvmlite.Ptr(pool, inner_ty_rp)
|
||||
return None
|
||||
# t.CPtr[T] / c.CPtr[T] 下标指针(含嵌套,如 t.CPtr[t.CPtr] → Ptr(Ptr(i8))):
|
||||
# 与定义侧 TypeGenResolve.resolve_annotation_type 的 Subscript(CPtr) 分支
|
||||
# (TypeGenResolve.vp L2769-2790)同口径 Ptr(resolve(T)),T 自身可含指针层级。
|
||||
# 先例:上方 rowptr[T] 分支(L1187-1200)同形(前缀 + 尾 ']' 判定 + 递归 + Ptr 包装)。
|
||||
# vpi 注解文本按源码原样缓存(如 `out: t.CUInt8T | t.CPtr[t.CPtr]`),本函数
|
||||
# 此前对该形态一律返回 None → 段被丢弃 → 联合坍缩到首段(i8),与定义侧
|
||||
# i8** 不一致(跨模块 declare/define ABI 错位;见 _resolve_vpi_ret_annot_str
|
||||
# 段循环内的同源判据)。
|
||||
cptr_sub_pfx: sizet = 0
|
||||
if string.strncmp(seg, "t.CPtr[", 7) == 0 or string.strncmp(seg, "c.CPtr[", 7) == 0:
|
||||
cptr_sub_pfx = 7
|
||||
if cptr_sub_pfx > 0:
|
||||
seg_len_cp: sizet = string.strlen(seg)
|
||||
if seg_len_cp > cptr_sub_pfx + 1 and seg[seg_len_cp - 1] == ']':
|
||||
inner_len_cp: sizet = seg_len_cp - cptr_sub_pfx - 1
|
||||
inner_buf_cp: bytes = stdlib.malloc(inner_len_cp + 1)
|
||||
if inner_buf_cp is not None:
|
||||
string.strncpy(inner_buf_cp, seg + cptr_sub_pfx, inner_len_cp)
|
||||
inner_buf_cp[inner_len_cp] = '\0'
|
||||
inner_ty_cp: llvmlite.LLVMType | t.CPtr = _resolve_single_vpi_type_str(
|
||||
pool, inner_buf_cp)
|
||||
stdlib.free(inner_buf_cp)
|
||||
if inner_ty_cp is not None:
|
||||
return llvmlite.Ptr(pool, inner_ty_cp)
|
||||
return None
|
||||
# t.XXX / c.XXX 内置类型映射
|
||||
if string.strncmp(seg, "t.", 2) == 0 or string.strncmp(seg, "c.", 2) == 0:
|
||||
attr_nm: str = seg + 2
|
||||
@@ -1326,6 +1351,16 @@ def _resolve_vpi_ret_annot_str(pool: rowptr[memhub.MemBuddy],
|
||||
first_qual: int = 0
|
||||
first_wl: int = 0
|
||||
first_td: int = 0
|
||||
# CPtr 下标段(t.CPtr[T]/c.CPtr[T],含嵌套)的联合合并参数:
|
||||
# cptr_sub_lvl = 该段解析后的外层 Ptr 层数 N(如 t.CPtr[t.CPtr] ⇒ 2);
|
||||
# cptr_sub_ty = 该段解析出的类型本身(无另一侧基类型时即结果)。
|
||||
# 判据与定义侧 TypeGenResolve.vp 的 `X | t.CPtr[T]` 分支(L2596-2639)同口径:
|
||||
# CPtr 侧贡献 N 层指针、另一侧提供基类型 ⇒ 结果 Ptr^N(基类型)。
|
||||
# 与 has_cptr(裸 t.CPtr 段)分开记录:裸标记路径恒"追加 1 层"且有 struct
|
||||
# 吸收特例(定义侧 L2540-2594),下标路径无吸收(定义侧 L2610-2639),
|
||||
# 两者在定义侧分属互斥分支(_is_cptr_marker / _is_cptr_subscript)。
|
||||
cptr_sub_lvl: int = 0
|
||||
cptr_sub_ty: llvmlite.LLVMType | t.CPtr = None
|
||||
|
||||
buf_len: sizet = string.strlen(ret_annot)
|
||||
pos: sizet = 0
|
||||
@@ -1347,7 +1382,35 @@ def _resolve_vpi_ret_annot_str(pool: rowptr[memhub.MemBuddy],
|
||||
break
|
||||
string.strncpy(seg_buf, ret_annot + seg_start, seg_len2)
|
||||
seg_buf[seg_len2] = '\0'
|
||||
if string.strcmp(seg_buf, "t.CPtr") == 0 or string.strcmp(seg_buf, "CPtr") == 0:
|
||||
# CPtr 下标段(t.CPtr[T]/c.CPtr[T],含嵌套如 t.CPtr[t.CPtr]):
|
||||
# 必须先行识别,不能落普通段分支取 first_ty——定义侧
|
||||
# TypeGenResolve.vp L2596-2639 对 `X | t.CPtr[T]` 是"CPtr 侧贡献
|
||||
# N 层指针、另一侧给基类型 ⇒ Ptr^N(X)",与"把该段本身当联合取值"
|
||||
# 语义不同(如 X=struct S、t.CPtr[t.CPtr]:定义侧 Ptr(Ptr(S)),
|
||||
# 取该段本身则得 i8**)。此处只记录 N 与段类型,末尾统一合并。
|
||||
if string.strncmp(seg_buf, "t.CPtr[", 7) == 0 or string.strncmp(seg_buf, "c.CPtr[", 7) == 0:
|
||||
seg_ty_cs: llvmlite.LLVMType | t.CPtr = _resolve_single_vpi_type_str(pool, seg_buf)
|
||||
if seg_ty_cs is not None:
|
||||
# 计算外层 Ptr 嵌套数(定义侧 L2616-2632 同口径)。注意不能在
|
||||
# case body 内更新 while 条件变量(自举编译的 match 会写到 subject
|
||||
# 快照槽 → 条件读旧槽死循环,见 TypeGenResolve.vp L2620-2624):
|
||||
# case 绑定 pointee 到局部变量,match 外更新循环变量。
|
||||
lvl_cs: int = 0
|
||||
cur_cs: llvmlite.LLVMType | t.CPtr = seg_ty_cs
|
||||
while cur_cs is not None:
|
||||
nxt_cs: llvmlite.LLVMType | t.CPtr = None
|
||||
match cur_cs:
|
||||
case llvmlite.LLVMType.Ptr(pointee_cs):
|
||||
lvl_cs += 1
|
||||
nxt_cs = pointee_cs
|
||||
case _:
|
||||
break
|
||||
cur_cs = nxt_cs
|
||||
# 多下标段取最大层数(定义侧按最外层联合右值合并,等价于层数累加)
|
||||
if lvl_cs > cptr_sub_lvl:
|
||||
cptr_sub_lvl = lvl_cs
|
||||
cptr_sub_ty = seg_ty_cs
|
||||
elif string.strcmp(seg_buf, "t.CPtr") == 0 or string.strcmp(seg_buf, "CPtr") == 0:
|
||||
has_cptr = 1
|
||||
elif string.strcmp(seg_buf, "t.CVoid") == 0 or string.strcmp(seg_buf, "CVoid") == 0:
|
||||
has_cvoid = 1
|
||||
@@ -1425,6 +1488,23 @@ def _resolve_vpi_ret_annot_str(pool: rowptr[memhub.MemBuddy],
|
||||
return llvmlite.Ptr(pool, first_ty)
|
||||
return i8_ptr_ty
|
||||
return i8_ptr_ty
|
||||
# CPtr 下标段联合合并(定义侧 TypeGenResolve.vp L2596-2639 同口径):
|
||||
# 有另一侧基类型 first_ty → 结果 = Ptr^N(first_ty)(N=cptr_sub_lvl)
|
||||
# 仅 CPtr 下标段自身 → 结果 = 该段解析类型本身(等价定义侧
|
||||
# Subscript(CPtr) 分支 L2769-2790 的 Ptr^N(inner))
|
||||
# 下标段无 struct 吸收(定义侧该分支不吸收),故不与上方 has_cptr 分支的
|
||||
# 吸收判据混用。has_cptr(裸 t.CPtr 段)在上一分支已全部返回,二者不叠加:
|
||||
# 定义侧裸标记(_is_cptr_marker)与下标标记(_is_cptr_subscript)亦互斥,
|
||||
# `X | t.CPtr | t.CPtr[...]` 这类混合写法本函数不建模(保持 has_cptr 旧行为)。
|
||||
if cptr_sub_lvl > 0:
|
||||
if first_ty is None:
|
||||
return cptr_sub_ty
|
||||
res_ty_cs: llvmlite.LLVMType | t.CPtr = first_ty
|
||||
wrap_i_cs: int = 0
|
||||
while wrap_i_cs < cptr_sub_lvl:
|
||||
res_ty_cs = llvmlite.Ptr(pool, res_ty_cs)
|
||||
wrap_i_cs += 1
|
||||
return res_ty_cs
|
||||
if has_cvoid != 0:
|
||||
# t.CVoid | t.State:State 是装饰器标记(编译侧忽略),t.CVoid → void。
|
||||
# 此前缺此分支 → first_ty=None → 返回 None → 跨模块函数返回类型
|
||||
|
||||
Reference in new issue
Block a user