docs(_Type): 类型系统收敛方案阶段 1/2/3 实施完成

This commit is contained in:
TermiNexus committed 2026-08-29 06:15:09 +08:00
1 parent 103c6ae865
commit 65dd4a5e3e
1 file changed
+69
+69
View File
@@ -83,3 +83,72 @@
- `_strappend` 越界存疑(TypeGenErr.vp L396)
- `_get_annotation_field_size` 缺类型白名单,未知类型按 8 字节(ClassGenEnum.vp L593-594)
- `infer_expr_type` 参数 bits 仅识别 8/16/64 三档,32 位静默落 i32(TypeGenErr.vp L295-300)
---
# 方案:类型系统收敛(t/c 库内部特判 + 正常库分析)
> 记录日期:2026-08-28
> 范围:TPV 侧(TPC 侧不再维护)
> 架构目标:t/c 库走编译器内部特判(map_t_type 保留核心原语);用户侧/库侧别名
> 链(from-import 别名、`X: t.CTypedef = Y`、stdint.vp 声明)走正常库分析(CTypedef
> 动态表递归);vpnci/vpi 存根仅供高亮插件,编译器不感知。
> **实施状态:阶段 1/2/3 已完成** ✅(2026-08-28)
## 现状缺口
1. **Name 分支无 from-import 别名反查**(TypeGenResolve.vp L1371-1502):
`from t import CInt as XXX` 后裸名 `XXX` 不在 struct/CTypedef/map_t_type 任何表 →
解析 None;`YYY: t.CTypedef = XXX` 链因此断(递归到 XXX 失败)。
2. **Attribute 路径硬编码优先**(L1539 map_t_type 先于 CTypedef L1590):stdint.vp 声明的
~70 个 typedef 名在 map_t_type 重复硬编码,限定名(stdint.INT)吃硬编码不吃库定义 → 双事实源。
3. **三张派生表未联动**:`__sizeof__`(CallGenDispatch L583-622)、REnum 尺寸
(ClassGenEnum L555-583)、无符号名单(ExprGenOps L261-287)各自重复硬编码。
## 阶段 1:补正常库分析(已完成)✅
### 1a. Name 分支 from-import 别名反查(TypeGenResolve.vp)
在 Name 分支 map_t_type 兜底之后插入:裸名 miss 时反查
`ImportsGen.lookup_from_import_original(from_imports, nm.id)`(from_imports 格式
`别名:模块:原始名`,返回内部指针需复制截断于空格/null)→ 用原始名 `_parse_type_string`
重建节点 → 递归 `resolve_annotation_type`。
- 效果:`from t import CInt as XXX` → XXX → CInt → map_t_type 命中;
`YYY: t.CTypedef = XXX` → YYY → CTypedef → "XXX" → 别名反查 → CInt ✅
- 防递归:复用 resolve_annotation_type 的 depth 上限;别名==原名时跳过
### 1b. Attribute 路径 CTypedef 动态表优先(TypeGenResolve.vp)
把 `map_t_type(at.attr)` 第一优先改为:先查 CTypedef 表(若 attr 是库 typedef 名且
已注册 → 递归展开),miss 再 map_t_type。
- 效果:`t.CInt` → attr="CInt" 表无 → map_t_type 特判(t/c 内部特判保留)✅;
`stdint.INT` → attr="INT" 表命中 → 动态递归(正常库分析)✅;表未注册时回落
map_t_type 硬编码兜底,不破坏现状
## 阶段 2:map_t_type 去重收敛(已完成)✅
删除 map_t_type 中与 stdint.vp 重复的 ~70 个名字(INT/BOOL/BYTE/WORD/HANDLE 之外的
大写别名、定长、小写简写、指针别名、int8_t/size_t/_Bool 等),保留 t/c 核心原语
(CInt/CUInt8T/CPtr/CBool/CNeedPtr 等)+ 内建小写 float/double + HANDLE/LPCSTR/LPCWSTR。
前置改造:新增统一口径 `TypeGenResolve.resolve_typedef_or_map`(CTypedef 动态表优先,
miss 回退 map_t_type)+ `get_type_size_bytes`(位宽/8)+ GenApi 委托;改造旁路调用点
VpiReader(_resolve_single_vpi_type_str 两处)、ClassGenEnum(_resolve_enum_member_type
两处)、TypeGenErr(参数位宽提取)为统一口径,确保删除后 BYTE 等仍能经库 typedef 解析。
## 阶段 3:三张派生表联动(已完成)✅
- `__sizeof__`(CallGenDispatch):尺寸表前插入 `get_type_size_bytes` 动态兜底
- REnum 尺寸(ClassGenEnum `_get_annotation_field_size`):加 pool 参数 + 动态兜底
- 无符号名单(ExprGenOps `_type_name_unsigned`):末尾加 CTypedef 展开兜底
(经 `_annot_str_unsigned` 子串判断符号性)
## 风险
- 1a 递归深度:复用现有 depth 上限,别名链过长即报错(fail-fast 优于卡死)
- 1b 解析来源变化:若 CTypedef 表值与 map_t_type 硬编码不一致,限定名结果改变——
需先对比验证(预期一致,stdint.vp 为权威)
- 阶段 2 删除后:纯 map_t_type 独有域(t/c 核心 CXXX、HANDLE/LPCSTR/LPCWSTR)保留,
其余靠注册,漏注册即编译期暴露(符合 fail-fast 原则)