fix(TypeGenResolve): 定长数组容器的「元素个数」实参不参与类名归属归一(消「保留裸名」误报)
【b 机制漏豁免】`_norm_type_arg_name` 规则 1.5 把 `Name[...]` 的**每个**顶层实参都递归
归一(目的是把类名统一成 `{定义模块SHA1}.类`)。但定长数组容器 `t.CArray[T, N]` /
`list[T, N]` 的**第 2 实参是元素个数**(编译期整数:CDefine 名 / 字面量 / 常量表达式,
依据是 TPC 侧 t.CArray 的定义原文"第一个参数为元素类型,第二个参数为数组大小(整数或
常量名)",lib/includes/t.py),对它做类名归属归一既无意义,又会落进规则 5.5 的
"保留裸名"取证 ⇒ 误报"类名归属缺失"。
现场:编译 includes/traceback.vp 时 TracebackState 的字段注解
`t.CArray[uint64, TRACEBACK_FRAME_BUF]`(traceback.vp:532),第 2 实参
'TRACEBACK_FRAME_BUF' 是 traceback.vp:482 的 `TRACEBACK_FRAME_BUF: t.CDefine = 128`
⇒ 每次编译刷
"[类型实参归属] 裸类名 'TRACEBACK_FRAME_BUF' 本次保留裸名…"ERROR。
修法:新增 `_is_count_arg_container(container)`(按**容器短名**判定,兼容 `tt.CArray`
这类别名;只认 CArray / list,泛型类 GSList[T]/Box[T] 的实参全是类型名不受影响),
规则 1.5 的实参拆分循环按序号跳过第 2 实参 —— 原样保留、不递归。
归一结果逐字不变:常量名与字面量既非类名也非 CTypedef,归一恒返回原串;TPC 侧
`ResolveTypeArgStr` 对同位置同样原样保留(Name→NormalizeGenericArgName / Constant→
unparse),两侧仍一致。改变的只是不再触发该取证日志。
配套:上一提交 d63787f 的 `_is_non_class_type_name` 覆盖同注解的**第 1 实参**
(`uint64` = builtins.vp 的 typedef)——两条判据互补:类型位放行非类名,个数位不归一。
未验证:需重新自举 TransPyV.exe 才生效。vast 解析通过。
This commit is contained in:
1 parent
d63787f8fc
commit
ef4421db20
1 file changed
+42
-4
@@ -262,6 +262,32 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 可 alloca");与 llvmlite 的跨模块 opaque 声明同一表示。
|
||||
return llvmlite.Struct(pool, None, -1, full)
|
||||
|
||||
def _is_count_arg_container(self, container: str) -> int:
|
||||
"""该容器的**第 2 个实参**是否为「元素个数」(编译期整数,不是类型名)。
|
||||
|
||||
依据是容器本身的定义(不是我猜的):TPC 侧 t.CArray 明写"第一个参数为元素类型,
|
||||
第二个参数为数组大小(整数或常量名)"(lib/includes/t.py CArray);`list[T, N]`
|
||||
是同义的定长数组写法(TPC _HandleListLlvm 的 'list[T, N]' 分支)。
|
||||
故这两个容器的第 2 实参是常量表达式 —— 对它做"裸类名 → {定义模块SHA1}.类"归一
|
||||
既无意义,又会落进 `_norm_type_arg_name` 规则 5.5 的"保留裸名"取证 ⇒ 误报为
|
||||
"类名归属缺失"。
|
||||
现场(2026-09-30):includes/traceback.vp:532
|
||||
`FrameAddr: t.CArray[uint64, TRACEBACK_FRAME_BUF]` 的第 2 实参
|
||||
'TRACEBACK_FRAME_BUF' 是 traceback.vp:482 的 `TRACEBACK_FRAME_BUF: t.CDefine = 128`。
|
||||
|
||||
判据只认**容器短名**(剥模块限定前缀,兼容 `tt.CArray` 这类别名):CArray / list。
|
||||
泛型类(list 之外的 GSList[T]、Box[T]…)的实参全是类型名,不受此判据影响。
|
||||
"""
|
||||
if container is None or container[0] == '\0':
|
||||
return 0
|
||||
_cname: str = container
|
||||
_c_dot: str = string.strrchr(container, '.')
|
||||
if _c_dot is not None:
|
||||
_cname = _c_dot + 1
|
||||
if string.strcmp(_cname, "CArray") == 0: return 1
|
||||
if string.strcmp(_cname, "list") == 0: return 1
|
||||
return 0
|
||||
|
||||
def _is_non_class_type_name(self, pool: memhub.MemBuddy*, name: str) -> int:
|
||||
"""该类型名是否**本就无类归属**(CTypedef / 语言内置标量 / 泛型形参)——不是类名。
|
||||
|
||||
@@ -408,6 +434,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 顶层联合已在第 1 步分割,此处 type_name 是纯泛型表示)。内部参数按
|
||||
# 顶层 ',' 分割后逐个递归 _norm_type_arg_name,再重组 "Name[arg1,arg2]"
|
||||
# ——保证所有 module 表示统一为 Hash Namespace({SHA1}.Class)。
|
||||
# 例外:定长数组容器(t.CArray / list)的**第 2 实参是元素个数**(编译期整数,
|
||||
# 不是类型名)⇒ 原样保留、不递归归一(判据与现场见 _is_count_arg_container)。
|
||||
lb_idx: sizet = seg_len
|
||||
ld: int = 0
|
||||
li2: sizet = 0
|
||||
@@ -454,6 +482,11 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
arg_start_g: sizet = 0
|
||||
cur_dep_g = 0
|
||||
ci_g = 0
|
||||
# 定长数组容器的第 2 实参是**元素个数**(CDefine 名/字面量/常量
|
||||
# 表达式),不是类型名 ⇒ 原样保留,不做类名归属归一(判据见
|
||||
# _is_count_arg_container;否则它会落进"保留裸名"取证误报)。
|
||||
_cntc_g: int = self._is_count_arg_container(container_g)
|
||||
_argi_g: int = 0
|
||||
while ci_g <= inner_len_g:
|
||||
is_sep_g: int = 0
|
||||
if ci_g < inner_len_g:
|
||||
@@ -471,11 +504,16 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if abuf_g is not None:
|
||||
string.strncpy(abuf_g, inner_buf_g + arg_start_g, alen_g)
|
||||
abuf_g[alen_g] = '\0'
|
||||
anorm_g: str = self._norm_type_arg_name(pool, abuf_g, from_imports)
|
||||
if anorm_g is not None:
|
||||
arg_list_g.append(anorm_g)
|
||||
else:
|
||||
if _cntc_g != 0 and _argi_g == 1:
|
||||
# 定长数组的元素个数位:常量表达式,原样保留
|
||||
arg_list_g.append(abuf_g)
|
||||
else:
|
||||
anorm_g: str = self._norm_type_arg_name(pool, abuf_g, from_imports)
|
||||
if anorm_g is not None:
|
||||
arg_list_g.append(anorm_g)
|
||||
else:
|
||||
arg_list_g.append(abuf_g)
|
||||
_argi_g += 1
|
||||
arg_start_g = ci_g + 1
|
||||
ci_g += 1
|
||||
# 重组 container[arg1,arg2,...]
|
||||
|
||||
Reference in new issue
Block a user