diff --git a/Projectrans.py b/Projectrans.py index 30ae344..973dab1 100644 --- a/Projectrans.py +++ b/Projectrans.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ProjectTrans.py - 工程级 TransPyC 翻译器""" -import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib/includes) +import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib) from lib.Projectrans import ( compute_sha1, _check_annotation_for_export, sha1_file, diff --git a/README.md b/README.md index 1e3811d..f6386b7 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ TransPyC 已用自身实现以下组件,证明其作为系统级语言的成 - **自研 LLVM IR 生成库** —— [includes/llvmlite/](includes/llvmlite/)(~1,500 LOC),用 TransPyC 自己写的 IR 文本生成器,18/18 测试通过 - **zlib 移植** —— [Test/ZlibTest/](Test/ZlibTest/),完整 deflate/inflate/huffman/checksum(~1,900 LOC) - **Win32 FFI 绑定** —— [includes/w32/](includes/w32/),file/memory/process/sync/console 全覆盖 -- **泛型容器** —— [includes/linkedlist.vp](includes/linkedlist.vp),`@t.NoVTable` + PEP 695 递归泛型继承 `class GNode(GSListNode[GNode])` +- **泛型容器** —— [includes/linkedlist.vp](includes/linkedlist.vp),`@NoVTable` + PEP 695 递归泛型继承 `class GNode(GSListNode[GNode])` ## 核心设计理念 @@ -37,8 +37,6 @@ Viper 语言通过两个核心模块提供类型和操作支持: | 模块 | 用途 | 导入方式 | |------|------|----------| -| `t` | 类型定义系统 | `import t` | -| `c` | C 语言操作指令 | `import c` | ## 快速上手 @@ -48,7 +46,6 @@ Viper 语言通过两个核心模块提供类型和操作支持: 4. **写第一个程序**: ```python -import t, c from stdint import * import stdio @@ -61,12 +58,12 @@ def main() -> CInt | CExport: | 文件 | 内容 | |------|------| -| [01-overview.md](wiki/01-overview.md) | 语言概述、两阶段编译流程、SHA1 命名空间、`t.CDefine`/`t.CExport`/`t.CInline` 深度解析 | +| [01-overview.md](wiki/01-overview.md) | 语言概述、两阶段编译流程、SHA1 命名空间、`CDefine`/`CExport`/`CInline` 深度解析 | | [02-type-system.md](wiki/02-type-system.md) | 类型系统(基本类型、指针、数组、结构体、联合体、枚举、typedef、`__attribute__`) | -| [03-variables.md](wiki/03-variables.md) | 变量声明与赋值(含 `t.CDefine` 常量) | -| [04-functions.md](wiki/04-functions.md) | 函数定义与调用(含 `t.CExport`、`t.CInline`、`t.CDefine` 函数、`-> tuple[...]` 多返回值) | +| [03-variables.md](wiki/03-variables.md) | 变量声明与赋值(含 `CDefine` 常量) | +| [04-functions.md](wiki/04-functions.md) | 函数定义与调用(含 `CExport`、`CInline`、`CDefine` 函数、`-> tuple[...]` 多返回值) | | [05-classes.md](wiki/05-classes.md) | 类与数据布局(结构体、联合体、枚举、typedef、位域) | -| [06-oop.md](wiki/06-oop.md) | 面向对象与运算符重载(`@t.Object`、`@t.CVTable`、`@t.NoVTable`、继承、dunder 方法) | +| [06-oop.md](wiki/06-oop.md) | 面向对象与运算符重载(`@Object`、`@CVTable`、`@NoVTable`、继承、dunder 方法) | | [07-control-flow.md](wiki/07-control-flow.md) | 控制流(条件、循环、match) | | [08-c-operations.md](wiki/08-c-operations.md) | C 语言操作(指针、内联汇编、FFI 外部函数声明、LLVM IR 内联) | | [09-exceptions.md](wiki/09-exceptions.md) | 异常处理 | diff --git a/StubGen.py b/StubGen.py index c9b2db8..9cb3137 100644 --- a/StubGen.py +++ b/StubGen.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """StubGen - C/H/Py 文件到 Python 存根文件生成器(工程化版本)""" -import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib/includes) +import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib) from lib.StubGen import StubGenConfig, PythonToStubConverter, StubGen, main diff --git a/Tools/AuditViperParseEntries.py b/Tools/AuditViperParseEntries.py index 1c39fc1..1c989d1 100644 --- a/Tools/AuditViperParseEntries.py +++ b/Tools/AuditViperParseEntries.py @@ -4,7 +4,7 @@ 背景(为什么需要这个门禁) Viper 前端 = TPC 自研 vast(`lib/vast`)+ **唯一展开点** `lib/core/SymbolUtils.ExpandSoftKeywords`(`fn/fun/func/function` → `def`; - `enum X:` 块 → `class X(t.CEnum):`,两者均同行替换、行号不变)。 + `enum X:` 块 → `class X(CEnum):`,两者均同行替换、行号不变)。 凡把 **Viper 源码文本**交给 `ast.parse` / `vast.parse` 的入口都必须先过这一层; 漏过者的失败形态是**静默降级**,不是报错:`includes/ast/base.vp:168` 的 `enum ASTFlag:` 曾让整个 base.vp 的声明(含顶层 `_init_ast`)一个都不注册, diff --git a/Tools/ScanAstFieldMiss.py b/Tools/ScanAstFieldMiss.py index d84ee7d..1e99d66 100644 --- a/Tools/ScanAstFieldMiss.py +++ b/Tools/ScanAstFieldMiss.py @@ -17,18 +17,18 @@ (如 "%s.__iter__" 之类的字符串与三引号注释块不再命中)。 5) 类成员表按族隔离: 基类先在**本族**找, 再找**支撑族**(''), 最后全局唯一名; 同一基类名跨族重复时报 AMBIG(宁可 UNRESOLVED 也不猜)。 - 6) `t.REnum`(tagged union)派生类: 变体字段合并进父类成员集 + 6) `REnum`(tagged union)派生类: 变体字段合并进父类成员集 (VPC 允许在父类指针上访问变体字段, 不合并会产生大量误报)。 前端 = **TPC 自研 vast**(`lib/vast`,与 StubGen/Converter.py 用的 `import vast as ast` 是同一源文件; 不可用 CPython `ast`, 否则含 `list[X*]` 等 vast 专有写法的文件会整体 SyntaxError 被跳过)。vast 与 CPython ast 的差异及本脚本的适配: - A) `X*` / `X**` 被 vast 脱糖成 `X | t.CPtr`(`**` 加两层), 其中合成的 - `t.CPtr` Attribute 节点**连 lineno 属性都没有**(编译器内部脱糖产物, 不是源码里的 - 访问; 全树实测 555 个, 全部是 ('t','CPtr'))=> 计入 Uses 时用 + A) `X*` / `X**` 被 vast 脱糖成 `X | CPtr`(`**` 加两层), 其中合成的 + `CPtr` Attribute 节点**连 lineno 属性都没有**(编译器内部脱糖产物, 不是源码里的 + 访问; 全树实测 555 个, 全部是 ('CPtr'))=> 计入 Uses 时用 `getattr(Node,'lineno',None) is not None` 排除。 B) vast 的 SyntaxError 可能不带 lineno(C 路径)=> 从报文 `at line N` 兜底提取。 - C) vast 的装饰器 `@t.NoVTable` 的 col_offset 是 `@` 的位置(CPython 是其后 1 列); + C) vast 的装饰器 `@NoVTable` 的 col_offset 是 `@` 的位置(CPython 是其后 1 列); 该 Attribute 的接收者 `t` 不是族指针, 判据不受影响。 D) 其余节点类名/属性名/walk/iter_child_nodes 与 CPython ast 同构(已逐节点对照)。 @@ -86,7 +86,7 @@ DefaultIncludesDir = os.path.join(RepoRoot, 'includes') DefaultOutFile = os.path.join(RepoRoot, 'Debugger', 'ScanAstFieldMiss.txt') # ---- 前端: TPC 自研 vast(非 CPython ast)。需要 TransPyC 包根在 sys.path, -# lib._bootstrap 会再补齐 lib/ 与 lib/includes(使 `import vast` 可用)。 +# lib._bootstrap 会再补齐 lib/(使 `import vast` 可用)。 if TpcRoot not in sys.path: sys.path.insert(0, TpcRoot) from lib import vast as ast # noqa: E402 @@ -105,8 +105,8 @@ ClassFields = {} ClassMethods = {} ClassBase = {} ClassLoc = {} # 裸类名 -> [族, ...](用于跨族基类解析) -EnumClass = {} # (族, 类名) -> 1 表示 t.REnum/t.CEnum 派生(变体字段合并) -REnumClass = {} # (族, 类名) -> 1 表示 t.REnum 派生(额外有编译器内建 .kind()) +EnumClass = {} # (族, 类名) -> 1 表示 REnum/CEnum 派生(变体字段合并) +REnumClass = {} # (族, 类名) -> 1 表示 REnum 派生(额外有编译器内建 .kind()) MemberCache = {} FamilyFields = {} # 族 -> 该族所有字段并集(OTHER/NOWHERE 判定用) @@ -190,7 +190,7 @@ def ParseSrc(Src, Path): """vast 前端解析入口(全脚本单一前端; 失败抛异常, 由调用方记账)。 `.vp` 源码须先过 Viper 软关键字层(`lib/core/SymbolUtils.ExpandSoftKeywords`: - `fn/fun/func/function` → `def`、`enum X:` → `class X(t.CEnum):`),与 + `fn/fun/func/function` → `def`、`enum X:` → `class X(CEnum):`),与 `StubGen/Converter.py` / `Shell/TransPyC.py` 等既有前端入口同口径。 否则含 `enum` 的 `.vp`(如 `includes/ast/base.vp:168`)会在此整体 SyntaxError, 被 `LoadInclude` 的正则兜底或 `RunScan` 的 `parsefail` 记成"解析失败"——两者 @@ -336,7 +336,7 @@ def Member(Fam, Name): # 2. 类型推导: 从注解 / cast 调用里取 (族, 类名) # ============================================================ def AnnClass(Ann): - """注解里若为 rawptr[<族>.](可被 `| t.CPtr` 包裹)返回 (族, X), 否则 None。""" + """注解里若为 rawptr[<族>.](可被 `| CPtr` 包裹)返回 (族, X), 否则 None。""" if Ann is None: return None if isinstance(Ann, ast.BinOp) and isinstance(Ann.op, ast.BitOr): @@ -464,8 +464,8 @@ def Walk(Node, Sc): Walk(S, CS) return if isinstance(Node, ast.Attribute): - # 只收源码里真实存在的属性访问: vast 脱糖 `X*` 会合成 `t.CPtr` Attribute, - # 该节点**连 lineno 属性都没有**(全树 555 个, 全为 ('t','CPtr')), 不是源码 + # 只收源码里真实存在的属性访问: vast 脱糖 `X*` 会合成 `CPtr` Attribute, + # 该节点**连 lineno 属性都没有**(全树 555 个, 全为 CPtr 下标), 不是源码 # 访问、也不能参与位置比较 => 用 getattr 显式排除。 if isinstance(Node.value, ast.Name) and getattr(Node, 'lineno', None) is not None: Uses.append((Node, Sc)) diff --git a/TransPyC.py b/TransPyC.py index 2c75703..bd21ef4 100644 --- a/TransPyC.py +++ b/TransPyC.py @@ -1,6 +1,6 @@ # TransPyC 入口程序 # 拆分后的模块位于 lib/Shell/ 目录下 -import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib/includes) +import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib) from lib.Shell import ( SerializeSymbolTable, deSerializeSymbolTable, diff --git a/lib/Projectrans/DeclarationGenerator.py b/lib/Projectrans/DeclarationGenerator.py index decacf3..4918840 100644 --- a/lib/Projectrans/DeclarationGenerator.py +++ b/lib/Projectrans/DeclarationGenerator.py @@ -7,8 +7,8 @@ from typing import List import llvmlite.ir as ir -from lib.includes import t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry from lib.core.SymbolUtils import ( IsListAnnotation, AnnotationContainsName, IsCPtrSubscriptNode, IsCPtrNode, IsRawPtrSubscriptNode, IsPtrSubscriptNode, ResolveGenericTypeArgStr, @@ -53,13 +53,13 @@ class DeclarationGenerator: # HandlesClassDef._generic_class_templates 同源(ClassDef 的 type_params # 标记),generate() 里从本模块 pyi 与 class_def_map 收集 self._generic_class_names: set[str] = set() - # t/c 导入名表(from t import CInt as myint → 'myint' → ('t','CInt')), - # 与定义端 Trans._t_c_imported_names 同口径,供泛型实参串解析使用 - self._t_c_imported_names: dict[str, tuple[str, str]] = {} + # 内建类型导入名表(CInt as myint → 'myint' → CInt), + # 与定义端 Trans._from_import_aliases 同口径,供泛型实参串解析使用 + self._from_import_aliases: dict[str, tuple[str, str]] = {} # 跨模块类定义映射:{class_name: ClassDef_node},供 _get_inherited_members # 查找其他模块定义的父类(如 exprs.py 的 Name(AST) 查找 base.py 的 AST) self._cross_module_class_defs: dict[str, ast.ClassDef] = class_def_map or {} - t.configure_platform(self.target_triple) + TypeSystem.configure_platform(self.target_triple) def generate(self, pyi_content: str, src_path: str) -> str: # 传 src_path:解析失败时报错/回退诊断才带得上来源(否则 vast 记为 , @@ -83,20 +83,9 @@ class DeclarationGenerator: if global_typedef_map: self.typedef_map.update(global_typedef_map) - # 构建 t/c 类型别名映射(from t import CInt as myint) + # 类型标记按裸名直接识别、不依赖导入:别名映射表保持为空。 self._t_alias_map: dict[str, type] = {} - self._t_c_imported_names: dict[str, tuple[str, str]] = {} - for node in ast.iter_child_nodes(tree): - if isinstance(node, ast.ImportFrom): - if node.module in ('t', 'c'): - for alias in node.names: - name: str = alias.name - asname: str = alias.asname or name - self._t_c_imported_names[asname] = (node.module, name) - if node.module == 't': - t_cls: type | None = getattr(t, name, None) - if isinstance(t_cls, type) and issubclass(t_cls, t.CType): - self._t_alias_map[asname] = t_cls + self._from_import_aliases: dict[str, tuple[str, str]] = {} for node in ast.iter_child_nodes(tree): if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name): @@ -112,6 +101,8 @@ class DeclarationGenerator: is_typedef = True elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Attribute) and hasattr(node.annotation.left, 'attr') and node.annotation.left.attr == 'CTypedef': is_typedef = True + elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Name) and node.annotation.left.id == 'CTypedef': + is_typedef = True if is_typedef: if node.value: self.typedef_map[var_name] = node.value @@ -191,14 +182,18 @@ class DeclarationGenerator: MultiRetTypes: list[ast.AST] = [] if node.decorator_list: for decorator in node.decorator_list: - # fail-fast:`@c.CReturn` 装饰器已移除,任何地方出现都必须报错, - # 不得静默忽略或改写;多返回值请改用 `-> tuple[ty1, ty2, ...]`。 - if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute): - if decorator.func.attr == 'CReturn': - raise SyntaxError( - f"函数 '{node.name}':`@c.CReturn` 已移除:请改用返回注解 " - f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)" - ) + # fail-fast:`CReturn` 不是内建标记;多返回值请改用 `-> tuple[ty1, ty2, ...]`。 + _DecName: str = '' + if isinstance(decorator, ast.Call): + if isinstance(decorator.func, ast.Name): + _DecName = decorator.func.id + elif isinstance(decorator.func, ast.Attribute): + _DecName = decorator.func.attr + if _DecName == 'CReturn': + raise SyntaxError( + f"函数 '{node.name}':`CReturn` 不是内建标记;请改用返回注解 " + f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)" + ) if node.returns: if isinstance(node.returns, ast.Subscript) and isinstance(node.returns.value, ast.Name) and node.returns.value.id == 'tuple': slice_node: ast.AST = node.returns.slice @@ -245,7 +240,7 @@ class DeclarationGenerator: return self._check_annotation_for_export(node.returns) def _check_annotation_for_export(self, annotation: ast.AST | None) -> bool: - """递归检查类型注解中是否包含 CExport 或 t.State""" + """递归检查类型注解中是否包含 CExport 或 State""" return bool(annotation) and (AnnotationContainsName(annotation, 'CExport') or AnnotationContainsName(annotation, 'State')) def _generate_global_decl(self, node: ast.AnnAssign) -> str | None: @@ -254,8 +249,8 @@ class DeclarationGenerator: return None var_name: str = node.target.id # CDefine 是编译期常量,不是变量:stub 里**不得**生成 external global。 - # `define X: T = V` 会展开为注解 `T | t.CDefine`,故判据必须能识别**联合形态**—— - # 原判据只认裸 `t.CDefine`(注解为单个 Attribute),联合注解会漏判 → + # `define X: T = V` 会展开为注解 `T | CDefine`,故判据必须能识别**联合形态**—— + # 原判据只认裸 `CDefine`(注解为单个 Attribute),联合注解会漏判 → # stub 出现 `@X = external global i32` → 其他模块引用它时变成未定义符号(链接失败), # 且会遮住跨模块 CDefine 常量回退(同名全局优先于常量)。与 _check_annotation_for_export # 一样用递归判据。 @@ -267,11 +262,13 @@ class DeclarationGenerator: return None if isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Attribute) and hasattr(node.annotation.left, 'attr') and node.annotation.left.attr == 'CTypedef': return None + if isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Name) and node.annotation.left.id == 'CTypedef': + return None if isinstance(node.annotation, ast.List): for elt in node.annotation.elts: if isinstance(elt, ast.Attribute) and hasattr(elt, 'attr') and elt.attr in ('CTypedef', 'Callable'): return None - if isinstance(elt, ast.Subscript) and isinstance(elt.value, ast.Attribute) and isinstance(elt.value.value, ast.Name) and elt.value.value.id == 't' and elt.value.attr == 'Callable': + if isinstance(elt, ast.Subscript) and isinstance(elt.value, ast.Name) and elt.value.id == 'Callable': return None VarType: str = self._get_type_str(node.annotation) if VarType.startswith('[0 x ') and node.value: @@ -305,28 +302,28 @@ class DeclarationGenerator: Returns: 'enum' | 'union' | 'renum' | 'struct' | 'ctype_marker' | None """ - # 1) 查 t 别名映射(from t import CEnum as en) + # 1) 查内建类型别名映射 if base_name in self._t_alias_map: t_cls: type = self._t_alias_map[base_name] - if issubclass(t_cls, (t.CEnum, t.REnum)): - return 'renum' if issubclass(t_cls, t.REnum) else 'enum' - if issubclass(t_cls, t.CUnion): + if issubclass(t_cls, (TypeSystem.CEnum, TypeSystem.REnum)): + return 'renum' if issubclass(t_cls, TypeSystem.REnum) else 'enum' + if issubclass(t_cls, TypeSystem.CUnion): return 'union' - if issubclass(t_cls, t.CStruct): + if issubclass(t_cls, TypeSystem.CStruct): return 'struct' # CType 及其子类(CChar/CInt/CVoid/CPtr 等)是"类型强转"标记, # 不应被编译为真实结构体,也不应被生成 stub 声明。 - if issubclass(t_cls, t.CType): + if issubclass(t_cls, TypeSystem.CType): return 'ctype_marker' - # 2) 直接查 t 模块属性 - t_cls: type | None = getattr(t, base_name, None) - if isinstance(t_cls, type) and issubclass(t_cls, t.CType): - if issubclass(t_cls, (t.CEnum, t.REnum)): - return 'renum' if issubclass(t_cls, t.REnum) else 'enum' - if issubclass(t_cls, t.CUnion): + # 2) 直接查内建类型类 + t_cls: type | None = getattr(TypeSystem, base_name, None) + if isinstance(t_cls, type) and issubclass(t_cls, TypeSystem.CType): + if issubclass(t_cls, (TypeSystem.CEnum, TypeSystem.REnum)): + return 'renum' if issubclass(t_cls, TypeSystem.REnum) else 'enum' + if issubclass(t_cls, TypeSystem.CUnion): return 'union' - if issubclass(t_cls, t.CStruct): + if issubclass(t_cls, TypeSystem.CStruct): return 'struct' # CType 及其子类是"类型强转"标记,不编译为结构体。 return 'ctype_marker' @@ -453,15 +450,7 @@ class DeclarationGenerator: is_novtable: bool = False if hasattr(node, 'decorator_list') and node.decorator_list: for decorator in node.decorator_list: - if isinstance(decorator, ast.Attribute): - if getattr(decorator.value, 'id', None) == 't': - if decorator.attr == 'CVTable': - is_cvtable = True - elif decorator.attr == 'Object': - is_cpython_object = True - elif decorator.attr == 'NoVTable': - is_novtable = True - elif isinstance(decorator, ast.Name): + if isinstance(decorator, ast.Name): if decorator.id == 'CVTable': is_cvtable = True elif decorator.id == 'Object': @@ -485,7 +474,7 @@ class DeclarationGenerator: base_name = base.value.id if base_name and not self._is_marker_base(base_name): has_parent_class = True - # 检查父类是否为 @t.NoVTable(非多态继承) + # 检查父类是否为 @NoVTable(非多态继承) _p_node: ast.ClassDef | None = None for n in ast.iter_child_nodes(self._pyi_tree): if isinstance(n, ast.ClassDef) and n.name == base_name: @@ -495,16 +484,14 @@ class DeclarationGenerator: _p_node = self._cross_module_class_defs.get(base_name) if _p_node is not None and hasattr(_p_node, 'decorator_list') and _p_node.decorator_list: for dec in _p_node.decorator_list: - if isinstance(dec, ast.Attribute) and getattr(dec.value, 'id', None) == 't' and dec.attr == 'NoVTable': - parent_is_novtable = True - elif isinstance(dec, ast.Name) and dec.id == 'NoVTable': + if isinstance(dec, ast.Name) and dec.id == 'NoVTable': parent_is_novtable = True break # 仅当非 NoVTable 且父类非 NoVTable 时才因继承启用 CVTable - # (@t.NoVTable 标记的类及其子类不使用 vtable,字段展平嵌入) + # (@NoVTable 标记的类及其子类不使用 vtable,字段展平嵌入) if has_parent_class and not is_cvtable and not is_novtable and not parent_is_novtable: is_cvtable = True - # 方法级 virtual(`virtual def m(...)` ⇒ 方法装饰器 @t.CVTable)触发类级 vtable: + # 方法级 virtual(`virtual def m(...)` ⇒ 方法装饰器 @CVTable)触发类级 vtable: # 与 HandlesClassDef._resolve_class_flags / VPC _detect_vtable_status 的 # `_has_any_func_cvtable` 分支逐条对齐(类级 NoVTable / 无真实父类)。 # 必须在此同步:定义模块按 IsCVTable 在 struct 首部放 vptr,若 stub 不同步, @@ -535,9 +522,7 @@ class DeclarationGenerator: _base_node = self._cross_module_class_defs.get(base_name) if _base_node is not None and hasattr(_base_node, 'decorator_list') and _base_node.decorator_list: for dec in _base_node.decorator_list: - if isinstance(dec, ast.Attribute) and getattr(dec.value, 'id', None) == 't' and dec.attr == 'CVTable': - base_has_vtable = True - elif isinstance(dec, ast.Name) and dec.id == 'CVTable': + if isinstance(dec, ast.Name) and dec.id == 'CVTable': base_has_vtable = True if base_has_vtable: break @@ -836,14 +821,14 @@ class DeclarationGenerator: init_len = len(item.value.value) + 1 VarType = f'[{init_len} x {elem_type}]' else: - # 固定大小数组: t.CArray[elem_type, count] → [count x elem_type] + # 固定大小数组: CArray[elem_type, count] → [count x elem_type] if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2: elem_type = self._get_type_str(slice_node.elts[0], embedded=True) count_val: int = self._get_const_int(slice_node.elts[1]) if count_val > 0: VarType = f'[{count_val} x {elem_type}]' elif isinstance(slice_node, (ast.Attribute, ast.Name, ast.Subscript)): - # 单参数 t.CArray[elem_type] → 指针模式 + # 单参数 CArray[elem_type] → 指针模式 elem_type = self._get_type_str(slice_node, embedded=True) VarType = f'{elem_type}*' member_types.append(VarType) @@ -910,15 +895,7 @@ class DeclarationGenerator: is_novtable: bool = False if hasattr(node, 'decorator_list') and node.decorator_list: for decorator in node.decorator_list: - if isinstance(decorator, ast.Attribute): - if getattr(decorator.value, 'id', None) == 't': - if decorator.attr == 'CVTable': - is_cvtable = True - elif decorator.attr == 'Object': - is_cpython_object = True - elif decorator.attr == 'NoVTable': - is_novtable = True - elif isinstance(decorator, ast.Name): + if isinstance(decorator, ast.Name): if decorator.id == 'CVTable': is_cvtable = True elif decorator.id == 'Object': @@ -951,9 +928,7 @@ class DeclarationGenerator: _base_node = self._cross_module_class_defs.get(base_name) if _base_node is not None and hasattr(_base_node, 'decorator_list') and _base_node.decorator_list: for dec in _base_node.decorator_list: - if isinstance(dec, ast.Attribute) and getattr(dec.value, 'id', None) == 't' and dec.attr == 'CVTable': - base_has_vtable = True - elif isinstance(dec, ast.Name) and dec.id == 'CVTable': + if isinstance(dec, ast.Name) and dec.id == 'CVTable': base_has_vtable = True if base_has_vtable: break @@ -1071,7 +1046,7 @@ class DeclarationGenerator: 替换策略:使用 i8*(不透明指针)代替 T*,而非具体类型指针。 原因:跨模块场景中,具体类型指针的 SHA1 前缀可能与导入模块不一致, 导致 TransPyC 类型转换失败。i8* 作为通用指针类型,可安全赋值给 - 任何 Class | t.CPtr 注解的变量,运行时行为与 T* 相同(都是指针)。 + 任何 Class | CPtr 注解的变量,运行时行为与 T* 相同(都是指针)。 Args: member_types: 基类成员类型字符串列表 @@ -1139,28 +1114,28 @@ class DeclarationGenerator: return len(type_str) - len(type_str.rstrip('*')) def _merge_cptr_subscript(self, base_type: str, cptr_sub_type: str) -> str: - """base | t.CPtr[T] → Ptr^N(base_type),N = t.CPtr[T] 段自身指针层数。 + """base | CPtr[T] → Ptr^N(base_type),N = CPtr[T] 段自身指针层数。 与定义侧 VPC TypeGenResolve.vp:2610-2639 同口径:数 CPtr 侧已解析类型的 外层 Ptr 嵌套层 N(TypeGenResolve.vp:2616-2632),再给另一侧**纯外包** N 层 Ptr(TypeGenResolve.vp:2633-2639,对 struct 基类型亦不吸收)。 与 LLVMTypeMapper._resolve_bitor 的 IsCPtrSubscriptNode 分支(_add_pointer_levels 逐层追加)同口径,对同一批形态两处结果一致。 - 注:裸 | t.CPtr(非下标标记)仍走上方的 %"..."* 吸收分支,与本节无关。 + 注:裸 | CPtr(非下标标记)仍走上方的 %"..."* 吸收分支,与本节无关。 """ return base_type + '*' * self._ptr_level_of(cptr_sub_type) def _ptr_subscript_type_str(self, annotation: ast.Subscript) -> str: - """指针下标(rawptr[T] / t.CPtr[T] / 裸名 CPtr[T],判据见 + """指针下标(rawptr[T] / CPtr[T] / 裸名 CPtr[T],判据见 SymbolUtils.IsPtrSubscriptNode)→ LLVM 类型串。 与定义端同源:SymbolUtils.DesugarPtrSubscriptToUnion 把三者折叠为等价 - 联合写法 `T | t.CPtr` 后交 HandlesTypeMerge.MergeTypes,指针层数由 + 联合写法 `T | CPtr` 后交 HandlesTypeMerge.MergeTypes,指针层数由 _MergeAllComponentTypes 的"struct 基类型吸收一层 CPtr"决定 —— 裸类引用 的非 embedded 形式本身即指针('%"sha1.X"*'),再包一层会被吸收 → 结果 就是该指针本身;其余类型(标量 / 已是指针的 typedef / 泛型容器特化 / - 联合写法 / 嵌套指针下标)逐层外包。rawptr[...] 与 t.CPtr[...] 共用本条 - 规则(此前 t.CPtr[list[X]] 在此得 list[X]**、rawptr[list[X]] 得 + 联合写法 / 嵌套指针下标)逐层外包。rawptr[...] 与 CPtr[...] 共用本条 + 规则(此前 CPtr[list[X]] 在此得 list[X]**、rawptr[list[X]] 得 list[X]*,同一指针语义两种结果)。 """ inner: ast.AST = annotation.slice @@ -1172,20 +1147,20 @@ class DeclarationGenerator: return f'{inner_type}*' def _is_bare_class_ref_annotation(self, inner: ast.AST, inner_type: str) -> bool: - """节点是否为"裸类引用"(本身即指针 → 吸收一层 t.CPtr)。 + """节点是否为"裸类引用"(本身即指针 → 吸收一层 CPtr)。 与 _get_type_str 的既有约定一致:类引用的**非** embedded 形式本身就是 - 指针('%"sha1.X"*'),所以 `AST | t.CPtr` 合并后仍是该指针(定义端 + 指针('%"sha1.X"*'),所以 `AST | CPtr` 合并后仍是该指针(定义端 _MergeAllComponentTypes 的 struct 吸收)。联合写法(ast.BinOp)与指针 - 下标(rawptr[...] / t.CPtr[...])不是裸类引用——它们已自带指针层数, - 须逐层外包(rawptr[Node] | t.CPtr → Node**、ast.AST | t.CPtr | t.CPtr + 下标(rawptr[...] / CPtr[...])不是裸类引用——它们已自带指针层数, + 须逐层外包(rawptr[Node] | CPtr → Node**、ast.AST | CPtr | CPtr → AST**,与定义端整体拉平后只吸收一次 CPtr 一致)。 - **例外:纯装饰器标记联合**。`t.CExtern | X` / `t.CExport | X` / `t.State | X` + **例外:纯装饰器标记联合**。`CExtern | X` / `CExport | X` / `State | X` (vpi 记录的模块级全局就是这种写法,见 lib.Phase.Phase1.__init__.vpi 的 - `_mbuddy: t.CExtern | memhub.MemBuddy | t.CPtr`)里标记侧展开为**空串** + `_mbuddy: CExtern | memhub.MemBuddy | CPtr`)里标记侧展开为**空串** (CTypeRegistry.NameToLLVM('CExtern') == ''),该联合语义上仍是 X 这一个 - 裸类引用,故 `t.CExtern | X | t.CPtr` 必须与 `X | t.CPtr` 同判(吸收)—— + 裸类引用,故 `CExtern | X | CPtr` 必须与 `X | CPtr` 同判(吸收)—— 对齐 VPC TypeGenResolve 的第 3 条语义「ActualType | DecoratorMarker → ActualType」。漏此判据时联合被当成"已自带指针层数的左值"而多外包一层: 声明端 `%"sha1.X"**` 与定义端 `%"sha1.X"*` 差一层,消费模块里 @@ -1219,6 +1194,10 @@ class DeclarationGenerator: return 'void' if annotation.id in ('str', 'bytes'): return 'i8*' + # 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`,非真实类):按 + # CPtr 同形的一层指针(i8*)参与联合合并(`T | CRef` → T*)。 + if annotation.id in ('CRef', 'CTempRef'): + return 'i8*' llvm_type: str | None = CTypeRegistry.NameToLLVM(annotation.id) if llvm_type is not None: return llvm_type @@ -1249,7 +1228,7 @@ class DeclarationGenerator: if annotation.id in self.typedef_map: resolved_str: str = self._get_type_str(self.typedef_map[annotation.id], embedded=embedded) return resolved_str - # 检查 t 类型别名(from t import CInt as myint) + # 检查内建类型别名 if annotation.id in self._t_alias_map: t_cls: type = self._t_alias_map[annotation.id] llvm: str | None = CTypeRegistry.CTypeToLLVM(t_cls) @@ -1262,10 +1241,6 @@ class DeclarationGenerator: from lib.core.TypeAnnotationResolver import TypeAnnotationResolver as _DG_TAR _dg_bv: str | None = _DG_TAR.builtins_typedef_value(annotation.id) if _dg_bv: - if _dg_bv.startswith('t.'): - _dg_llvm: str | None = CTypeRegistry.NameToLLVM(_dg_bv[2:]) - if _dg_llvm: - return _dg_llvm _dg_node: ast.AST | None = None try: _dg_node = ast.parse(_dg_bv, '', mode='eval').body @@ -1280,8 +1255,8 @@ class DeclarationGenerator: return f'{sname}*' elif isinstance(annotation, ast.Attribute): attr_name: str = annotation.attr if hasattr(annotation, 'attr') else '' - # 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`,非真实类):按 t.CPtr - # 同形的「一层指针 = i8*」参与联合合并(`T | t.CRef` → T*),保证跨模块 + # 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`,非真实类):按 CPtr + # 同形的「一层指针 = i8*」参与联合合并(`T | CRef` → T*),保证跨模块 # .vpi 声明端类型与定义端 _ctype_to_llvm 一致。 if attr_name in ('CRef', 'CTempRef'): return 'i8*' @@ -1295,15 +1270,15 @@ class DeclarationGenerator: # 定义端以扁平名 `{外类}_{内类}` 发射(见 HandlesClassDef._EmitNestedClassDefs), # 故此处按扁平名拼类型;命中与否由 struct_names 里是否存在该扁平名裁决 # (不存在即维持下方既有路径,不改变任何既有类型名)。 - if module_name and module_name != 't' and module_name != 'c': + if module_name: NestedName: str = f'{module_name}_{attr_name}' if NestedName in self.struct_names: NestedSha1: str | None = self.struct_sha1_map.get(NestedName, self.module_sha1) NestedStr: str = f'%"{NestedSha1}.{NestedName}"' if NestedSha1 else f'%struct.{NestedName}' return NestedStr if embedded else f'{NestedStr}*' - if (module_name == 't' and attr_name == 'State') or attr_name == 'State': + if attr_name == 'State': return '' - if (module_name == 't' and attr_name == 'Callable') or attr_name == 'Callable': + if attr_name == 'Callable': return 'i8*' llvm_type: str | None = CTypeRegistry.NameToLLVM(attr_name) if llvm_type is not None: @@ -1348,23 +1323,23 @@ class DeclarationGenerator: return right_type if right_type not in ('', 'void') else (left_type or right_type) if right_type in ('', 'void'): return left_type - # t.CPtr (i8*) 与 left 合并:对齐 Phase 2 _MergeAllComponentTypes 的 - # "first CPtr absorption" 语义:struct | t.CPtr → struct*(吸收,struct 变量默认是指针)。 - # 但对于本身已是指针的类型(如 bytes=str=i8*),bytes | t.CPtr → i8**(不吸收)。 + # CPtr (i8*) 与 left 合并:对齐 Phase 2 _MergeAllComponentTypes 的 + # "first CPtr absorption" 语义:struct | CPtr → struct*(吸收,struct 变量默认是指针)。 + # 但对于本身已是指针的类型(如 bytes=str=i8*),bytes | CPtr → i8**(不吸收)。 # 例外:LLVM 聚合数组([N x T],字符串以 '[' 开头)不可再外包指针层 → i8*。 # 注:具名泛型特化(%"mod.list[X]"*)**不**走此回退——stub 已由 # _collect_undefined_type_decls 为其补 opaque 声明,保留名字才能与 define 端 # 的 %"mod.list[ast.ASTptr]"* 逐字一致(原 `'[' in left_type` 会把 - # list[X] | t.CPtr 一并退化成 i8*,与定义端 %"mod.list[X]"* 不一致)。 + # list[X] | CPtr 一并退化成 i8*,与定义端 %"mod.list[X]"* 不一致)。 if right_type == 'i8*': if left_type[:1] == '[': return 'i8*' if left_type in ('', 'void'): return 'i8*' # 吸收仅对"裸类引用"成立(其非 embedded 形式本身即指针): - # ast.AST | t.CPtr → %"sha1.AST"*。已自带指针层数的左值 - # (rawptr[...] / t.CPtr[...] 下标 / 联合写法)须逐层外包: - # rawptr[Node] | t.CPtr → Node**、ast.AST | t.CPtr | t.CPtr → AST** + # ast.AST | CPtr → %"sha1.AST"*。已自带指针层数的左值 + # (rawptr[...] / CPtr[...] 下标 / 联合写法)须逐层外包: + # rawptr[Node] | CPtr → Node**、ast.AST | CPtr | CPtr → AST** # ——与定义端 _CollectAllOperandTypes 整体拉平、只吸收一次 CPtr # (_MergeAllComponentTypes 的 base_ptr_count>0 分支)一致。 if self._is_bare_class_ref_annotation(annotation.left, left_type): @@ -1372,20 +1347,20 @@ class DeclarationGenerator: if '*' in left_type: return f'{left_type}*' return f'{left_type}*' - # X | t.CPtr[T](T 为下标段,非裸标记):CPtr 侧贡献自身指针层数 N, + # X | CPtr[T](T 为下标段,非裸标记):CPtr 侧贡献自身指针层数 N, # 另一侧外包 N 层(Ptr^N(X));左右两侧写法对称(定义侧 VPC # TypeGenResolve.vp:2604-2609 亦两侧皆判)。必须先于下方 # "'*' in left_type → 直接返回左值":否则左值本身已是指针 - # (BYTEPTR⇒i8*)时会吞掉右段层数(BYTEPTR | t.CPtr[t.CPtr] 改前得 i8*)。 + # (BYTEPTR⇒i8*)时会吞掉右段层数(BYTEPTR | CPtr[CPtr] 改前得 i8*)。 # LLVM 聚合([N x T] / { ... })不可再外包指针层,保持既有行为(只报不改)。 if IsCPtrSubscriptNode(annotation.right) and left_type[:1] not in ('[', '{'): return self._merge_cptr_subscript(left_type, right_type) if IsCPtrSubscriptNode(annotation.left) and right_type[:1] not in ('[', '{'): return self._merge_cptr_subscript(right_type, left_type) - # t.CPtr 裸标记在左侧(t.CPtr | X):与右侧写法(X | t.CPtr,见上) + # CPtr 裸标记在左侧(CPtr | X):与右侧写法(X | CPtr,见上) # 完全对称。缺此分支时左值 i8* 会吞掉右侧的指针层数: - # t.CPtr | rawptr[Node] 声明端曾得 i8*,而定义端为 %"sha1.Node"**(差一层)。 - # 仅对裸标记 t.CPtr 生效(left 为 t.CPtr[T] 下标走上一条分支; + # CPtr | rawptr[Node] 声明端曾得 i8*,而定义端为 %"sha1.Node"**(差一层)。 + # 仅对裸标记 CPtr 生效(left 为 CPtr[T] 下标走上一条分支; # str/bytes 等其它 i8* 左值不受影响)。 if IsCPtrNode(annotation.left) and right_type[:1] not in ('[', '{'): if self._is_bare_class_ref_annotation(annotation.right, right_type): @@ -1397,24 +1372,24 @@ class DeclarationGenerator: return right_type return left_type elif isinstance(annotation, ast.Subscript): - # 指针下标(rawptr[T] / t.CPtr[T] / 裸名 CPtr[T] / 导入别名 X[T],以及带 - # 模块前缀书写的 X.CPtr[T])≡ 源码联合写法 `T | t.CPtr`:与定义端 + # 指针下标(rawptr[T] / CPtr[T] / 裸名 CPtr[T] / 导入别名 X[T],以及带 + # 模块前缀书写的 X.CPtr[T])≡ 源码联合写法 `T | CPtr`:与定义端 # **同一判据**(SymbolUtils.IsPtrSubscriptNode,别名经本模块的 - # _t_c_imported_names 表解析 X→CPtr)+ 同一层数规则 + # _from_import_aliases 表解析 X→CPtr)+ 同一层数规则 # (_ptr_subscript_type_str:裸类引用吸收一层、其余逐层外包),内层 T # 照常解析(跨模块类由 struct_sha1_map 补 SHA1 前缀)。此前 rawptr[T] - # 在此退化成 i8*,t.CPtr[T] 走的是"embedded + 追加一层"的独立分支: - # 非同一规则,且对泛型容器特化多出一层(t.CPtr[list[X]] 得 list[X]**, + # 在此退化成 i8*,CPtr[T] 走的是"embedded + 追加一层"的独立分支: + # 非同一规则,且对泛型容器特化多出一层(CPtr[list[X]] 得 list[X]**, # 而 rawptr[list[X]] 得 list[X]*)。 ValueIsCPtr: bool = ( (isinstance(annotation.value, ast.Attribute) and annotation.value.attr == 'CPtr') or (isinstance(annotation.value, ast.Name) and annotation.value.id == 'CPtr') ) - if (IsPtrSubscriptNode(annotation, TCAliasMap=self._t_c_imported_names) + if (IsPtrSubscriptNode(annotation, TCAliasMap=self._from_import_aliases) or (ValueIsCPtr and isinstance(annotation.slice, (ast.Attribute, ast.Name, ast.Subscript)))): return self._ptr_subscript_type_str(annotation) # 内建裸名函数指针构造子 callable[...] / Callable[...]:与 Attribute 分支的 - # t.Callable[...] 逐点等价(同为 i8*)。缺此分支时落到下方 Name 泛型特化 / + # Callable[...] 逐点等价(同为 i8*)。缺此分支时落到下方 Name 泛型特化 / # 兜底返回 'i32'(现场 Repl.vp:307 `ReplFragFn: callable[[rawptr], int]` # 声明成 i32 全局 ⇒ 赋 i8* 触发「指针隐式转整数」)。 if isinstance(annotation.value, ast.Name) and (annotation.value.id == 'callable' or annotation.value.id == 'Callable'): @@ -1424,10 +1399,10 @@ class DeclarationGenerator: return f'[{self._get_const_int(annotation.slice)} x i8]' if isinstance(annotation.slice, ast.Constant) and isinstance(annotation.slice.value, int): return f'[{annotation.slice.value} x {base}]' - # 处理 t.CArray[elem_type, count] / rawarray[elem_type, count] / array[elem_type, count] + # 处理 CArray[elem_type, count] / rawarray[elem_type, count] / array[elem_type, count] # 注解 → [count x elem_type] - # 支持 t.CArray (ast.Attribute)、CArray/rawarray/array (ast.Name) 三种写法 - # (array 为本轮新增的内建软关键字,与 t.CArray 逐点等价) + # 支持 CArray (ast.Attribute)、CArray/rawarray/array (ast.Name) 三种写法 + # (array 为本轮新增的内建软关键字,与 CArray 逐点等价) ValueIsCArray: bool = ( (isinstance(annotation.value, ast.Attribute) and annotation.value.attr == 'CArray') or (isinstance(annotation.value, ast.Name) and annotation.value.id in ('CArray', 'rawarray', 'array')) @@ -1442,7 +1417,7 @@ class DeclarationGenerator: # count 为 None 或 0 → 零长度数组(外部符号) return f'[0 x {ElemType}]' elif isinstance(SliceNode, (ast.Attribute, ast.Name, ast.Subscript)): - # 单参数 t.CArray[elem_type]:与 t.CArray[elem_type, None] 语义统一为 + # 单参数 CArray[elem_type]:与 CArray[elem_type, None] 语义统一为 # "长度自动推导数组"。此处无初始化字面量可推导 → 与 ,None 分支同用 # [0 x elem] 占位,真实长度由 _generate_global_decl 按初始化字面量 # (List 长度 / str 长度+1) 修正。 @@ -1462,7 +1437,7 @@ class DeclarationGenerator: # 实参串走 SymbolUtils.ResolveGenericTypeArgStr(与定义端 # _mangle_generic_class_name 同一规则源):此前只认 Name / Name-Tuple # 实参,Attribute(ast.AST)/ Subscript(rawptr[...])/ BinOp - # (X | t.CPtr)/ 混合 Tuple 一律退回未特化的 %"...list"*, + # (X | CPtr)/ 混合 Tuple 一律退回未特化的 %"...list"*, # 与 define 端发射的 %".list[ast.ASTptr]" 不一致 # (Undefined method / 签名错位)。 # 内建容器(non_struct_types)之外,**用户泛型类**同样特化:判据 @@ -1482,7 +1457,7 @@ class DeclarationGenerator: gc_mangled: list[str] = [ ResolveGenericTypeArgStr( gc_node, - TCAliasMap=self._t_c_imported_names, + TCAliasMap=self._from_import_aliases, StructSha1Map=self.struct_sha1_map) for gc_node in gc_nodes] gc_spec: str = gc_name + '[' + ']['.join(gc_mangled) + ']' @@ -1496,7 +1471,7 @@ class DeclarationGenerator: gc_sha1: str | None = self.struct_sha1_map.get(gc_name, self.module_sha1) gc_sname: str = f'%"{gc_sha1}.{gc_spec}"' if gc_sha1 else f'%struct.{gc_spec}' # 一律以指针引用(不区分 embedded):定义端对嵌入式泛型容器 - # (字段 / t.CArray 元素)用不透明指针(实测字段 i8*,见 + # (字段 / CArray 元素)用不透明指针(实测字段 i8*,见 # FieldForms/FieldBox/FieldOrder),嵌入 unsized opaque # 结构体值会让字段/元素偏移错位;非 embedded(参数/返回) # 亦与定义端同为指针 @@ -1539,9 +1514,7 @@ class DeclarationGenerator: return f'{sname}*' return 'i8*' elif isinstance(annotation, ast.Call): - if isinstance(annotation.func, ast.Name) and annotation.func.id == 'callable': - return 'i8*' - if isinstance(annotation.func, ast.Attribute) and annotation.func.attr == 'Callable': + if isinstance(annotation.func, ast.Name) and annotation.func.id in ('callable', 'Callable'): return 'i8*' return 'i32' diff --git a/lib/Projectrans/Phase1Generator.py b/lib/Projectrans/Phase1Generator.py index ea0e3db..a54ca7a 100644 --- a/lib/Projectrans/Phase1Generator.py +++ b/lib/Projectrans/Phase1Generator.py @@ -11,7 +11,7 @@ from lib.Projectrans.DeclarationGenerator import DeclarationGenerator from lib.core.VLogger import get_logger as _vlog from lib.core.SymbolUtils import ExpandSoftKeywords from lib.constants.config import mode as _ConfigMode -from lib.includes import t +from lib.core import TypeSystem from StubGen import PythonToStubConverter # 全局缓存目录(不被 --clean 清除),用于缓存库文件的 .pyi / .stub.ll / .doc.json @@ -387,6 +387,8 @@ class Phase1Generator: is_typedef = True elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Attribute) and hasattr(node.annotation.left, 'attr') and node.annotation.left.attr == 'CTypedef': is_typedef = True + elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Name) and node.annotation.left.id == 'CTypedef': + is_typedef = True if is_typedef and node.value and var_name not in typedef_map: typedef_map[var_name] = node.value except Exception as _e: @@ -564,55 +566,55 @@ class Phase1Generator: return body[0].value.value return None - def _get_cached_pyi(self, src_path: str, module_name: str) -> str: - """读取源文件并转换为 .pyi 内容;同一 (路径, 模块名) 且 mtime+size 未变时复用模块级缓存。 - - 覆盖 _process_file_pyi 与 _process_include_py_files_pyi 两个入口, - 避免对未变化的文件重复 open+read+convert(mtime+size 一致即视为内容未变, - 与 _get_sha1 的 manifest 判定一致)。 - """ - abs_path: str = os.path.abspath(src_path) - key: tuple[str, str] = (abs_path, module_name) - try: - st: os.stat_result = os.stat(abs_path) - except OSError: - st = None - if st is not None: - cached: tuple[float, int, str] | None = _PYI_CONVERT_CACHE.get(key) - if cached is not None and cached[0] == st.st_mtime and cached[1] == st.st_size: - return cached[2] - with open(abs_path, 'r', encoding='utf-8') as f: - content: str = f.read() - sig_content: str = PythonToStubConverter.convert(content, module_name) - if len(_PYI_CONVERT_CACHE) >= _PYI_CACHE_MAX_SIZE: - _PYI_CONVERT_CACHE.clear() - if st is not None: - _PYI_CONVERT_CACHE[key] = (st.st_mtime, st.st_size, sig_content) - return sig_content - - def _get_cached_docstrings(self, src_path: str) -> dict[str, str]: - """读取源文件并提取 docstring;同一路径且 mtime+size 未变时复用模块级缓存。 - - 返回的 dict 仅供调用方 json.dump 只读使用,调用方不修改,故可安全复用缓存对象。 - """ - abs_path: str = os.path.abspath(src_path) - try: - st: os.stat_result = os.stat(abs_path) - except OSError: - st = None - if st is not None: - cached: tuple[float, int, dict[str, str]] | None = _PYI_DOC_CACHE.get(abs_path) - if cached is not None and cached[0] == st.st_mtime and cached[1] == st.st_size: - return cached[2] - with open(abs_path, 'r', encoding='utf-8') as f: - content: str = f.read() - docs: dict[str, str] = self._extract_docstrings(content) - if len(_PYI_DOC_CACHE) >= _PYI_CACHE_MAX_SIZE: - _PYI_DOC_CACHE.clear() - if st is not None: - _PYI_DOC_CACHE[abs_path] = (st.st_mtime, st.st_size, docs) - return docs - + def _get_cached_pyi(self, src_path: str, module_name: str) -> str: + """读取源文件并转换为 .pyi 内容;同一 (路径, 模块名) 且 mtime+size 未变时复用模块级缓存。 + + 覆盖 _process_file_pyi 与 _process_include_py_files_pyi 两个入口, + 避免对未变化的文件重复 open+read+convert(mtime+size 一致即视为内容未变, + 与 _get_sha1 的 manifest 判定一致)。 + """ + abs_path: str = os.path.abspath(src_path) + key: tuple[str, str] = (abs_path, module_name) + try: + st: os.stat_result = os.stat(abs_path) + except OSError: + st = None + if st is not None: + cached: tuple[float, int, str] | None = _PYI_CONVERT_CACHE.get(key) + if cached is not None and cached[0] == st.st_mtime and cached[1] == st.st_size: + return cached[2] + with open(abs_path, 'r', encoding='utf-8') as f: + content: str = f.read() + sig_content: str = PythonToStubConverter.convert(content, module_name) + if len(_PYI_CONVERT_CACHE) >= _PYI_CACHE_MAX_SIZE: + _PYI_CONVERT_CACHE.clear() + if st is not None: + _PYI_CONVERT_CACHE[key] = (st.st_mtime, st.st_size, sig_content) + return sig_content + + def _get_cached_docstrings(self, src_path: str) -> dict[str, str]: + """读取源文件并提取 docstring;同一路径且 mtime+size 未变时复用模块级缓存。 + + 返回的 dict 仅供调用方 json.dump 只读使用,调用方不修改,故可安全复用缓存对象。 + """ + abs_path: str = os.path.abspath(src_path) + try: + st: os.stat_result = os.stat(abs_path) + except OSError: + st = None + if st is not None: + cached: tuple[float, int, dict[str, str]] | None = _PYI_DOC_CACHE.get(abs_path) + if cached is not None and cached[0] == st.st_mtime and cached[1] == st.st_size: + return cached[2] + with open(abs_path, 'r', encoding='utf-8') as f: + content: str = f.read() + docs: dict[str, str] = self._extract_docstrings(content) + if len(_PYI_DOC_CACHE) >= _PYI_CACHE_MAX_SIZE: + _PYI_DOC_CACHE.clear() + if st is not None: + _PYI_DOC_CACHE[abs_path] = (st.st_mtime, st.st_size, docs) + return docs + def _process_file_pyi(self, src_path: str, rel_path: str) -> None: # 增量优化:先用 mtime+size 获取 sha1,未变更文件跳过 open+read sha1: str = self._get_sha1(src_path) @@ -687,13 +689,13 @@ class Phase1Generator: exception_names: set[str] = set() struct_sha1_map: dict[str, str] = {} class_def_map: dict[str, ast.ClassDef] = {} - # 预先收集所有 CType 子类名称(来自 t 模块和别名映射), + # 预先收集所有 CType 子类名称(来自内建类型模型), # 用于在 struct 注册表中跳过"类型强转"标记类。 ctype_marker_names: set[str] = set() - for attr_name in dir(t): - t_cls: type | None = getattr(t, attr_name, None) - if isinstance(t_cls, type) and issubclass(t_cls, t.CType) and t_cls is not t.CType: - if not issubclass(t_cls, (t.CEnum, t.REnum, t.CUnion, t.CStruct)): + for attr_name in dir(TypeSystem): + t_cls: type | None = getattr(TypeSystem, attr_name, None) + if isinstance(t_cls, type) and issubclass(t_cls, TypeSystem.CType) and t_cls is not TypeSystem.CType: + if not issubclass(t_cls, (TypeSystem.CEnum, TypeSystem.REnum, TypeSystem.CUnion, TypeSystem.CStruct)): ctype_marker_names.add(t_cls.__name__) ctype_marker_names.add(attr_name) valid_sha1_keys: set[str] = set(self.sha1_map.keys()) @@ -742,7 +744,7 @@ class Phase1Generator: elif base.id in ctype_marker_names: is_ctype_marker = True break - # 也检查装饰器形式 @t.CEnum / @t.REnum + # 也检查装饰器形式 @CEnum / @REnum if not is_enum and not is_renum and not is_exception and not is_ctype_marker and hasattr(node, 'decorator_list') and node.decorator_list: for deco in node.decorator_list: deco_attr: str | None = None diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index 9f65031..e260735 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -17,7 +17,7 @@ from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode from lib.core.Handles.HandlesBase import CTypeInfo from lib.core.SymbolData import ModuleSymbols -from lib.includes import t +from lib.core import TypeSystem from lib.core.SymbolUtils import AnnotationContainsName, ExpandSoftKeywords, DefineDeclIntTypeFromAnnotation from lib.core.SymbolUtils import ClassHasFuncLevelCVTable, IsVtableSlotMethod from lib.Projectrans.Utils import compute_sha1, _check_annotation_for_export, find_reachable_files_from_entries, topological_sort_files, parse_python_file @@ -609,11 +609,11 @@ def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object], """从 .pyi 文件中提取 CDefine 常量到 all_dc。文件不存在时静默跳过。 治本修复:原实现只支持 ast.Constant 和 float() 调用, - 无法处理 t.CUnsignedLong(-11)(ast.Call)和 + 无法处理 CUnsignedLong(-11)(ast.Call)和 FOREGROUND_GREEN | FOREGROUND_INTENSITY(ast.BinOp)等复杂表达式。 现使用 ConstEvaluator.eval_full 统一求值,支持: - ast.Constant: 简单常量 (0x0002) - - ast.Call: 类型构造 (t.CUnsignedLong(-11)) + - ast.Call: 类型构造 (CUnsignedLong(-11)) - ast.BinOp: 位运算 (FOREGROUND_RED | FOREGROUND_GREEN) - ast.UnaryOp: 一元运算 (-11) - ast.Name: 引用其他 CDefine 常量 @@ -643,10 +643,10 @@ def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object], if AnnotationContainsName(node.annotation, 'CDefine') and node.value: val: object = ConstEvaluator.eval_full(node.value, ctx) if val is None and isinstance(node.value, ast.Call) and len(node.value.args) == 1: - # 类型构造的**裸别名**形态(如 `DWORD(-11)`,非 `t.CUnsignedLong(-11)`): - # eval_full 只认 `t.X(...)` / `from t import X`(见 ConstEvaluator + # 类型构造的**裸别名**形态(如 `DWORD(-11)`,非 `CUnsignedLong(-11)`): + # eval_full 只认 `X(...)` / `from t import X`(见 ConstEvaluator # _eval_compile_time_call),裸 typedef 别名既不在 _t_module 也不在 - # mock ctx 的 _t_type_symbols 里 → 返回 None → 该常量被整条丢弃。 + # mock ctx 的 _builtin_type_symbols 里 → 返回 None → 该常量被整条丢弃。 # 现场:win32file.vp 的 STD_INPUT/OUTPUT/ERROR_HANDLE 是全仓**唯一**用 # 别名构造写的 define → 唯独这三个进不了 _all_define_constants,导致 # 模块属性访问 `wf.STD_ERROR_HANDLE` 解析落空、退化成未定义的全局符号 @@ -668,7 +668,7 @@ def _CountUnresolvedTypedefs(module_symbols: object) -> int: """该模块"有值注解却解析不出类型"的 typedef 个数(供声明阶段判断是否要下一轮)。 typedef 右侧可以引用**其它模块**的 typedef:例 win32base 的 - `HANDLE: t.CTypedef = VOIDPTR`(VOIDPTR 在 stdint)——本模块先 stage 时右侧 + `HANDLE: CTypedef = VOIDPTR`(VOIDPTR 在 stdint)——本模块先 stage 时右侧 解析为空(original_type_kind/original_class 均为 None),要等依赖模块入表后 重 stage 才能补全。返回 0 表示本模块声明已完整(不再需要重跑)。 """ @@ -3132,7 +3132,7 @@ class Phase2Translator: sys.exit(1) def _precollect_vtable_state(self) -> None: - """预扫描 includes .py 文件,收集 @t.CVTable 类的虚表信息。 + """预扫描 includes .py 文件,收集 @CVTable 类的虚表信息。 并行编译(ProcessPoolExecutor)创建独立内存的 worker 进程, vtable 状态必须预收集并通过 pickle 共享。 @@ -3150,7 +3150,7 @@ class Phase2Translator: code, tree = parse_python_file(py_path) # 字符串预过滤:不含 CVTable 的文件跳过 AST 遍历。 # `virtual class` / `virtual def` 修饰符在源码里写的是 `virtual` - # (AST 上才变成 @t.CVTable 装饰器),故预过滤必须同时放行 + # (AST 上才变成 @CVTable 装饰器),故预过滤必须同时放行 # `virtual`/`novirtual`,否则含修饰符的 includes 类会被整段跳过—— # 静默不预收集虚表状态(与本题"不得静默丢弃修饰符"同族问题)。 if tree is None or ('CVTable' not in code and 'virtual' not in code): @@ -3161,10 +3161,7 @@ class Phase2Translator: continue has_cvtable: bool = False for dec in node.decorator_list: - if isinstance(dec, ast.Attribute): - if getattr(dec.value, 'id', None) == 't' and dec.attr == 'CVTable': - has_cvtable = True - elif isinstance(dec, ast.Name): + if isinstance(dec, ast.Name): if dec.id == 'CVTable': has_cvtable = True # 方法级 virtual 触发类级 vtable(与 @@ -3199,7 +3196,7 @@ class Phase2Translator: # 构造函数不放入 vtable(避免子类与基类 vtable 大小不一致破坏多态分派) if method_name in ('__new__', '__init__', '__before_init__'): continue - # 方法级修饰符:`novirtual def`(⇒ @t.NoVTable)不进槽; + # 方法级修饰符:`novirtual def`(⇒ @NoVTable)不进槽; # 判据唯一源 = SymbolUtils.IsVtableSlotMethod,与 # HandlesClassDef / VPC _should_method_be_virtual 同口径。 if not IsVtableSlotMethod(item, class_level_cvtable): @@ -4370,7 +4367,7 @@ class Phase2Translator: info.IsInline = True info.InlineBody = node.body info.InlineParams = [arg.arg for arg in node.args.args] - info.Storage = t.CInline() + info.Storage = TypeSystem.CInline() self.inline_func_symbols[func_name] = info self.inline_func_symbols[sym_key] = info except Exception as _e: @@ -4440,7 +4437,7 @@ class Phase2Translator: # ① 声明阶段(全部模块;多轮直到"本轮没有新增可解析的声明") # 单轮仍会与模块顺序有关:typedef 右侧可以引用**其它模块**的 typedef, - # 例 win32base 的 `HANDLE: t.CTypedef = VOIDPTR`,VOIDPTR 在 stdint + # 例 win32base 的 `HANDLE: CTypedef = VOIDPTR`,VOIDPTR 在 stdint # ⇒ 本模块先 stage 时右侧解析为空;下一轮把它重 stage 一遍(重 stage 覆盖 # 登记,条目随依赖入表而变完整)。无进展即停,最多再跑一轮。 _stage_map: dict[tuple[str, str], ModuleSymbols] = {} diff --git a/lib/Projectrans/Utils.py b/lib/Projectrans/Utils.py index c91c3ba..b7f6649 100644 --- a/lib/Projectrans/Utils.py +++ b/lib/Projectrans/Utils.py @@ -41,7 +41,7 @@ _FILE_AST_CACHE: dict[str, tuple[float, str, ast.Module]] = {} def _check_annotation_for_export(annotation: ast.AST | None) -> bool: - """递归检查类型注解中是否包含 CExport/CExtern/State(t.State = t.CExtern | t.CExport)""" + """递归检查类型注解中是否包含 CExport/CExtern/State(State = CExtern | CExport)""" if not annotation: return False return (AnnotationContainsName(annotation, 'CExport') or @@ -78,7 +78,7 @@ def parse_python_file(filepath: str) -> tuple[str, ast.Module] | tuple[str, None except Exception: return ('', None) try: - # 软关键字/语法糖展开:fn/fun/func/function -> def、enum 块 -> class X(t.CEnum) + # 软关键字/语法糖展开:fn/fun/func/function -> def、enum 块 -> class X(CEnum) # (均同行替换,行号不变),供 ast.parse 使用。 # 注意 content 保持原始文本返回(compute_sha1 必须与 Phase1 一致), # 仅 tree 基于展开后的代码解析。 diff --git a/lib/Projectrans/__init__.py b/lib/Projectrans/__init__.py index 727be8e..39999fc 100644 --- a/lib/Projectrans/__init__.py +++ b/lib/Projectrans/__init__.py @@ -1,5 +1,5 @@ """Projectrans 包 - 工程级 TransPyC 翻译器""" -import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib/includes) +import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib) from lib.core.VLogger import Logger, LogLevel, set_logger diff --git a/lib/Shell/TransPyC.py b/lib/Shell/TransPyC.py index d98a250..48fe9c0 100644 --- a/lib/Shell/TransPyC.py +++ b/lib/Shell/TransPyC.py @@ -8,8 +8,7 @@ import datetime import tempfile import subprocess from typing import Any -from lib.includes import c -from lib.includes import t +from lib.core import TypeSystem from lib.constants.config import ( DEFAULT_INPUT_FILE, DEFAULT_OUTPUT_FILE, DEFAULT_COMPILE_COMMAND, @@ -449,7 +448,7 @@ class TransPyC: self.translator.OriginalLines = Content.split('\n') self.translator.Content = Content - # 解析Python代码为AST + # 解析Python代码为AST Tree: ast.Module = ast.parse(Content, InputFile) # 解析文件以提取类型信息(用于 EmbeddedAssignments) @@ -549,14 +548,13 @@ class TransPyC: if isinstance(_node, ast.Import): for _alias in _node.names: _name: str = _alias.name - if _name in ('c', 't'): - continue + # t / c 库已退役:不再跳过,按常规模块登记 self.translator._ImportedModules.add(_name) if _alias.asname: self.translator.SymbolTable.import_aliases[_alias.asname] = _name elif isinstance(_node, ast.ImportFrom): _module_name: str | None = _node.module - if _module_name and _module_name not in ('c', 't'): + if _module_name: self.translator._ImportedModules.add(_module_name) for _alias in _node.names: if _alias.asname: diff --git a/lib/StubGen/Converter.py b/lib/StubGen/Converter.py index ac79b32..82b93ee 100644 --- a/lib/StubGen/Converter.py +++ b/lib/StubGen/Converter.py @@ -88,19 +88,12 @@ class PythonToStubConverter: StubLines.append('"""') StubLines.append('') - # 解析 Python 代码,检查是否已经导入了 t 和 c(AST 与下方主解析复用,避免重复 parse) - HasImportT: bool = False - HasImportC: bool = False + # 解析 Python 代码,供下方主循环复用(避免重复 parse)。 + # stub 头部不注入 import 行;内建标记按裸名使用,无需导入。 + tree: ast.Module | None = None try: # 传来源名:解析失败时 vast 的报错/回退诊断才带得上模块名(否则记为 ) - tree: ast.Module = ast.parse(PyContent, f'{ModuleName}.vp') - for node in tree.body: - if isinstance(node, ast.Import): - for alias in node.names: - if alias.name == 't': - HasImportT = True - elif alias.name == 'c': - HasImportC = True + tree = ast.parse(PyContent, f'{ModuleName}.vp') except SyntaxError: # 语法错误:同一内容两次解析结果必然相同,与主循环 fail-fast 行为一致 raise @@ -108,16 +101,6 @@ class PythonToStubConverter: # 非语法类解析异常:保持原语义(第一遍吞掉,主循环重新解析后向上传播) tree = None - # 添加默认导入(如果源代码中没有) - if not HasImportT: - StubLines.append('import t') - if not HasImportC: - StubLines.append('import c') - if not HasImportT or not HasImportC: - StubLines.append('') - - StubLines.append('') - # 解析 Python 代码,提取类型定义(复用上方的 parse 结果) try: if tree is None: @@ -130,7 +113,7 @@ class PythonToStubConverter: if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name): TypeStr: str = PythonToStubConverter._GetTypeString(node.annotation) # 检查是否是 Postdefinition 类型 - if 't.Postdefinition' in TypeStr: + if 'Postdefinition' in TypeStr: # 提取引用的类名 ClassName: str | None = PythonToStubConverter._ExtractPostdefClass(node.annotation) if ClassName: @@ -167,10 +150,10 @@ class PythonToStubConverter: CurrentType = 'variable' # 跳过 Postdefinition 变量(已经在类中处理) TypeStr = PythonToStubConverter._GetTypeString(node.annotation) - if 't.Postdefinition' in TypeStr: + if 'Postdefinition' in TypeStr: continue - # 检查是否带有 t.CStatic 标志,如果有则不排除 - HasStatic: bool = 't.CStatic' in TypeStr + # 检查是否带有 CStatic 标志,如果有则不排除 + HasStatic: bool = 'CStatic' in TypeStr # 检查变量是否应该被排除 ShouldExclude: bool = False if isinstance(node.target, ast.Name) and not HasStatic: @@ -210,7 +193,7 @@ class PythonToStubConverter: StubLines.append('') StubLines.append(ImportStr) elif isinstance(node, ast.Expr): - # 处理模块级别的宏调用,如 c.CUndef(...) / c.CPragma(...) + # 处理模块级别的宏调用,如 CUndef(...) / CPragma(...) ExprStr: str = PythonToStubConverter._GetExprString(node.value) if ExprStr: CurrentType = 'macro' @@ -364,8 +347,8 @@ class PythonToStubConverter: else: lines.append(f'{MemberIndent}{item.target.id}: {TypeStr}') continue - # 检查是否是宏变量(类型包含 t.CDefine) - if 't.CDefine' in TypeStr: + # 检查是否是宏变量(类型包含 CDefine) + if 'CDefine' in TypeStr: # 检查宏变量是否应该被排除 if isinstance(item.target, ast.Name): MacroName: str = item.target.id @@ -400,7 +383,7 @@ class PythonToStubConverter: if count_expr and count_expr != 'None': has_size = True elem_type_str: str = PythonToStubConverter._GetTypeString(slice_node.elts[0]) - FinalTypeStr = f't.CArray[{elem_type_str}, {count_expr}]' + FinalTypeStr = f'CArray[{elem_type_str}, {count_expr}]' if not has_size: elem_type_str = PythonToStubConverter._GetTypeString(slice_node if not isinstance(slice_node, ast.Tuple) else slice_node.elts[0]) init_len: int = 0 @@ -410,9 +393,9 @@ class PythonToStubConverter: elif isinstance(item.value, ast.Constant) and isinstance(item.value.value, str): init_len = len(item.value.value) + 1 if init_len > 0: - FinalTypeStr = f't.CArray[{elem_type_str}, {init_len}]' + FinalTypeStr = f'CArray[{elem_type_str}, {init_len}]' else: - FinalTypeStr = f't.CArray[{elem_type_str}, None]' + FinalTypeStr = f'CArray[{elem_type_str}, None]' if item.value is not None and isinstance(item.value, ast.Constant): try: value_repr: str = ast.unparse(item.value) @@ -426,7 +409,7 @@ class PythonToStubConverter: FuncStub: list[str] = PythonToStubConverter._ConvertFunction(item, indent=indent+1, SourceLines=SourceLines, class_name=node.name) lines.extend(FuncStub) elif isinstance(item, ast.Expr): - # 处理宏调用,如 c.CUndef(...) / c.CPragma(...) + # 处理宏调用,如 CUndef(...) / CPragma(...) ExprStr: str = PythonToStubConverter._GetExprString(item.value) if ExprStr: lines.append(f'{IndentStr} {ExprStr}') @@ -443,9 +426,9 @@ class PythonToStubConverter: FilteredLines: list[str] = [] for line in NestedClassLines: # 跳过宏守卫相关行 - if line.strip().startswith('c.CIfndef(') or line.strip().startswith('c.CEndif()'): + if line.strip().startswith('CIfndef(') or line.strip().startswith('CEndif()'): continue - if ': t.CDefine' in line and '__' in line: + if ': CDefine' in line and '__' in line: continue FilteredLines.append(line) lines.extend(FilteredLines) @@ -467,11 +450,11 @@ class PythonToStubConverter: lines: list[str] = [] IndentStr: str = ' ' * indent - # 检查是否是宏函数(返回类型包含 t.CDefine) + # 检查是否是宏函数(返回类型包含 CDefine) is_macro_func: bool = False if node.returns: ReturnType: str = PythonToStubConverter._GetTypeString(node.returns) - if 't.CDefine' in ReturnType: + if 'CDefine' in ReturnType: is_macro_func = True # 如果是宏函数,检查是否应该被排除 @@ -558,11 +541,11 @@ class PythonToStubConverter: ParamStr: str = ', '.join(params) - # 返回类型 - 保持原始类型(不添加t.State) + # 返回类型 - 保持原始类型(不添加 State) if node.returns: ReturnType = PythonToStubConverter._GetTypeString(node.returns) else: - ReturnType = 't.CInt' + ReturnType = 'CInt' TypeParamStr: str = '' if hasattr(node, 'type_params') and node.type_params: @@ -579,8 +562,8 @@ class PythonToStubConverter: if isinstance(node.target, ast.Name): VarName: str = node.target.id TypeStr: str = PythonToStubConverter._GetTypeString(node.annotation) - # 检查是否是宏变量(类型包含 t.CDefine) - if 't.CDefine' in TypeStr: + # 检查是否是宏变量(类型包含 CDefine) + if 'CDefine' in TypeStr: # 检查宏变量是否应该被排除 if PythonToStubConverter._ShouldExcludeMacro(VarName): return lines # 返回空列表,排除该宏 @@ -593,15 +576,15 @@ class PythonToStubConverter: else: lines.append(f'{VarName}: {TypeStr}') return lines - # 非宏变量:不加 t.State + # 非宏变量:不加 State # 含有 typedef 的变量不加 extern,普通变量需要加 extern - has_typedef: bool = 't.CTypedef' in TypeStr or 'CTypedef' in TypeStr + has_typedef: bool = 'CTypedef' in TypeStr or 'CTypedef' in TypeStr if has_typedef and node.value is not None: ValueTypeStr: str = PythonToStubConverter._GetTypeString(node.value) lines.append(f'{VarName}: {TypeStr} = {ValueTypeStr}') else: - if not has_typedef and 't.CExtern' not in TypeStr and 't.CStatic' not in TypeStr: - TypeStr = f't.CExtern | {TypeStr}' + if not has_typedef and 'CExtern' not in TypeStr and 'CStatic' not in TypeStr: + TypeStr = f'CExtern | {TypeStr}' lines.append(f'{VarName}: {TypeStr}') return lines @@ -623,7 +606,7 @@ class PythonToStubConverter: if inferred_type: lines.append(f'{VarName}: {inferred_type}') else: - lines.append(f'{VarName}: t.CInt') + lines.append(f'{VarName}: CInt') return lines @@ -632,33 +615,33 @@ class PythonToStubConverter: """从值推断 C 类型""" if isinstance(value, ast.Constant): if isinstance(value.value, int): - return 't.CInt' + return 'CInt' elif isinstance(value.value, float): - return 't.CDouble' + return 'CDouble' elif isinstance(value.value, str): - return 't.CCharPtr' + return 'CCharPtr' elif isinstance(value.value, bool): - return 't.CInt' + return 'CInt' elif isinstance(value, ast.List): - return 't.CVoidPtr' + return 'CVoidPtr' elif isinstance(value, ast.Dict): - return 't.CVoidPtr' + return 'CVoidPtr' elif isinstance(value, ast.Name): - return 't.CInt' + return 'CInt' elif isinstance(value, ast.BinOp): left_type: str | None = PythonToStubConverter._InferTypeFromValue(value.left) if left_type: return left_type - return 't.CInt' + return 'CInt' elif isinstance(value, ast.Call): # 函数调用返回值,假设为指针类型 if isinstance(value.func, ast.Name): func_name: str = value.func.id if func_name == 'malloc': - return 't.CVoidPtr' + return 'CVoidPtr' elif func_name in ('ctypes.cast', 'cast'): - return 't.CVoidPtr' - return 't.CVoidPtr' + return 'CVoidPtr' + return 'CVoidPtr' return None @staticmethod @@ -668,19 +651,19 @@ class PythonToStubConverter: 支持集与 VPC(ViperC/App/lib/Stub/StubGen/Converter.vp 的 _PyiTypeStr) 等价:Name/Attribute/Subscript/BinOp/UnaryOp/Compare/BoolOp/Constant/ List/Call(VPC 另支持裸 Tuple,本侧仅在 Subscript.slice 位置接受 Tuple)。 - 未支持的节点种类与运算符在此 fail-fast(不自造 't.CVoid' 回落)。 + 未支持的节点种类与运算符在此 fail-fast(不自造 'CVoid' 回落)。 """ - # 无注解(None):调用方未提供注解,沿用原语义返回 't.CVoid'; + # 无注解(None):调用方未提供注解,沿用原语义返回 'CVoid'; # 这不是"未知节点"——未知节点走函数尾 fail-fast。 if annotation is None: - return 't.CVoid' + return 'CVoid' if isinstance(annotation, ast.Name): return annotation.id elif isinstance(annotation, ast.Attribute): if isinstance(annotation.value, ast.Name): return f'{annotation.value.id}.{annotation.attr}' else: - # 处理嵌套属性访问,如 t.attr.packed + # 处理嵌套属性访问,如 attr.packed ParentStr: str = PythonToStubConverter._GetTypeString(annotation.value) return f'{ParentStr}.{annotation.attr}' elif isinstance(annotation, ast.Subscript): @@ -692,20 +675,20 @@ class PythonToStubConverter: SliceStr = PythonToStubConverter._GetTypeString(annotation.slice) return f'{base}[{SliceStr}]' elif isinstance(annotation, ast.BinOp): - # 处理 BinOp,如 t.CExtern | fd_table.__set_default__(...) + # 处理 BinOp,如 CExtern | fd_table.__set_default__(...) left: ast.AST = annotation.left right: ast.AST = annotation.right - # 值引用参数标记:联合形态 `T | t.CRef`(ref)/ `T | t.CTempRef`(temp) + # 值引用参数标记:联合形态 `T | CRef`(ref)/ `T | CTempRef`(temp) # 还原为源码写法 `&T` / `&temp T`,使跨模块 .vpi 往返保留取址模式。 if isinstance(annotation.op, ast.BitOr): _ref_kind: str | None = None _type_side: ast.AST | None = None - if isinstance(right, ast.Attribute) and right.attr in ('CRef', 'CTempRef'): - _ref_kind = right.attr + if isinstance(right, ast.Name) and right.id in ('CRef', 'CTempRef'): + _ref_kind = right.id _type_side = left - elif isinstance(left, ast.Attribute) and left.attr in ('CRef', 'CTempRef'): - _ref_kind = left.attr + elif isinstance(left, ast.Name) and left.id in ('CRef', 'CTempRef'): + _ref_kind = left.id _type_side = right if _ref_kind is not None and _type_side is not None: _inner: str = PythonToStubConverter._GetTypeString(_type_side) @@ -790,7 +773,7 @@ class PythonToStubConverter: elements: list[str] = [PythonToStubConverter._GetTypeString(elem) for elem in annotation.elts] return f'[{", ".join(elements)}]' elif isinstance(annotation, ast.Call): - # 处理函数调用形式的类型注解,如 t.Postdefinition(xxa) 或 callable(t.CVoid, app_id = t.CInt) + # 处理函数调用形式的类型注解,如 Postdefinition(xxa) 或 callable(CVoid, app_id = CInt) # 如果是 __set_default__ 调用,只返回函数名部分 if isinstance(annotation.func, ast.Attribute) and annotation.func.attr in ('__set_default__', '__set_default'): return PythonToStubConverter._GetTypeString(annotation.func.value) @@ -807,8 +790,8 @@ class PythonToStubConverter: else: return f'{FuncStr}({ArgsStr})' # 未知/未支持的注解节点 fail-fast(与 VPC StubGen 的 _PyiTypeStr 同语义、 - # 同文案、同类型):静默回落 't.CVoid' 会把错误类型写进 stub 签名——实例: - # 源里的 t.Callable[[], int] 曾写成 t.Callable[int, int](见 + # 同文案、同类型):静默回落 'CVoid' 会把错误类型写进 stub 签名——实例: + # 源里的 Callable[[], int] 曾写成 Callable[int, int](见 # ViperApps/ViperOS/VKernel/__vpcbuild__/temp/0b/0bb176432facf634.vpi:23), # 下游按错误签名解析且无任何提示。 # 归因信息:节点 kind + 行号;文件归因由调用方在日志里带上 @@ -822,10 +805,10 @@ class PythonToStubConverter: def _ExtractPostdefClass(annotation: ast.AST) -> str | None: """从 Postdefinition 类型注解中提取类名 - 例如:t.Postdefinition(__buddy_system) -> '__buddy_system' - t.Postdefinition(xxx) | t.CTypedef -> 'xxx' + 例如:Postdefinition(__buddy_system) -> '__buddy_system' + Postdefinition(xxx) | CTypedef -> 'xxx' """ - # 处理 BinOp (如: t.Postdefinition(xxx) | t.CTypedef) + # 处理 BinOp (如: Postdefinition(xxx) | CTypedef) if isinstance(annotation, ast.BinOp): # 递归检查左操作数 left_result: str | None = PythonToStubConverter._ExtractPostdefClass(annotation.left) @@ -837,10 +820,10 @@ class PythonToStubConverter: return right_result return None - # 处理函数调用 (如: t.Postdefinition(__buddy_system)) + # 处理函数调用 (如: Postdefinition(__buddy_system)) if isinstance(annotation, ast.Call): FuncStr: str = PythonToStubConverter._GetTypeString(annotation.func) - if FuncStr == 't.Postdefinition' and annotation.args: + if FuncStr == 'Postdefinition' and annotation.args: # 提取第一个参数 first_arg: ast.AST = annotation.args[0] if isinstance(first_arg, ast.Name): @@ -964,7 +947,7 @@ class PythonToStubConverter: return f'{decorator.value.id}.{decorator.attr}' return decorator.attr elif isinstance(decorator, ast.Call): - # 处理带参数的装饰器,如 @c.Attribute(t.attr.packed) + # 处理带参数的装饰器,如 @Attribute(attr.packed) FuncStr: str = PythonToStubConverter._GetDecoratorString(decorator.func) ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in decorator.args]) return f'{FuncStr}({ArgsStr})' @@ -974,8 +957,8 @@ class PythonToStubConverter: def _GetExprString(expr: ast.AST) -> str: """获取表达式字符串(用于宏调用)""" if isinstance(expr, ast.Call): - # 处理函数调用,如 c.CUndef(...), c.CPragma(...) - # (旧的 c.CIf/c.CElif/c.CElse 已删除:cif/celif/celse 由 _ProcessIfMacro 渲染) + # 处理函数调用,如 CUndef(...), CPragma(...) + # (旧的 CIf/CElif/CElse 已删除:cif/celif/celse 由 _ProcessIfMacro 渲染) FuncStr: str = PythonToStubConverter._GetDecoratorString(expr.func) if FuncStr and ('CEndif' in FuncStr or 'CUndef' in FuncStr or 'CPragma' in FuncStr): ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in expr.args]) @@ -984,9 +967,9 @@ class PythonToStubConverter: @staticmethod def _RestoreDefinedMarkers(node: ast.AST) -> ast.AST: - """把内部标记 c.@CIfdef(N) 递归还原为 defined(N) 调用(供 stub 文本渲染)。 + """把内部标记 @CIfdef(N) 递归还原为 defined(N) 调用(供 stub 文本渲染)。 - cif/celif 条件的 desugar 会把 defined(NAME) 变成 c.@CIfdef(NAME) 标记调用; + cif/celif 条件的 desugar 会把 defined(NAME) 变成 @CIfdef(NAME) 标记调用; 生成 .vpi 文本时必须还原为用户可写的 defined(NAME),否则存根不可再解析。 """ if isinstance(node, ast.Call): @@ -1011,7 +994,7 @@ class PythonToStubConverter: @staticmethod def _CifConditionText(test: ast.AST) -> str | None: - """cif/celif 条件文本:内部标记 c.@CIf(EXPR) → EXPR;c.@CIfdef(N) → defined(N)。 + """cif/celif 条件文本:内部标记 @CIf(EXPR) → EXPR;@CIfdef(N) → defined(N)。 返回 None 表示 test 不是 cif 族标记(普通 if 的运行时条件)。 """ diff --git a/lib/__init__.py b/lib/__init__.py index ce986a4..f8be6e0 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -1,6 +1,6 @@ """TransPyC 编译器核心库 任何 ``import lib.*`` 都会先触发 _bootstrap(sys.path 设置: -项目根 + lib 目录 + lib/includes),保证 ``import vast`` 直接可用。 +项目根 + lib 目录),保证 ``import vast`` 直接可用。 """ import lib._bootstrap # noqa: F401 diff --git a/lib/_bootstrap.py b/lib/_bootstrap.py index 4365e01..d7ca194 100644 --- a/lib/_bootstrap.py +++ b/lib/_bootstrap.py @@ -2,7 +2,7 @@ 在首次导入时一次性设置好编译器运行所需的 sys.path: - 项目根目录:让 ``import TransPyC``、``from StubGen import``、动态 importlib 能解析 -- lib/includes:让用户注解模块中的 ``import t`` / ``import c`` 能解析 +(lib 目录加入 sys.path,使 ``import vast`` 直接可用。) 入口点(TransPyC.py / Projectrans.py)应在最开头 ``import lib._bootstrap``。 lib 内部模块也可 ``import lib._bootstrap`` 作为安全网,重复导入是无副作用的 no-op。 @@ -25,16 +25,12 @@ def _bootstrap() -> None: _LibDir: str = os.path.dirname(os.path.abspath(__file__)) # 项目根目录 = lib 的父目录 _ProjectRoot: str = os.path.dirname(_LibDir) - # lib/includes 目录(编译器内部类型系统 t.py / c.py) - _IncludesDir: str = os.path.join(_LibDir, 'includes') if _ProjectRoot not in sys.path: sys.path.insert(0, _ProjectRoot) if _LibDir not in sys.path: # lib 目录入 path:使 vast 包(lib/vast/)可直接 import vast sys.path.append(_LibDir) - if _IncludesDir not in sys.path: - sys.path.append(_IncludesDir) # ============================================================ # LLVM IR 兼容性补丁:llvmlite 不允许 void* 指针类型 diff --git a/lib/core/ConstEvaluator.py b/lib/core/ConstEvaluator.py index 07a0009..f3bd0e2 100644 --- a/lib/core/ConstEvaluator.py +++ b/lib/core/ConstEvaluator.py @@ -20,9 +20,9 @@ from typing import Any, Callable, Optional, TYPE_CHECKING import llvmlite.ir as ir from lib.core.Handles.HandlesBase import CTypeInfo -# 治本修复:导入 t 模块和 CType 基类,用于类型构造调用求值(如 t.CUnsignedLong(-11)) -from lib.includes import t as _t_module -from lib.includes.t import CType as _CType_base +# 导入 TypeSystem 与 CType 基类,用于类型构造调用求值(如 CUnsignedLong(-11)) +from lib.core import TypeSystem as _t_module +from lib.core.TypeSystem import CType as _CType_base if TYPE_CHECKING: from lib.core.LlvmCodeGenerator import LlvmCodeGenerator @@ -50,40 +50,33 @@ class ConstEvaluator: return info.DefineValue return None if isinstance(node, ast.Attribute): - # 先尝试 t.CSizeT().Size 模式(类型构造调用 + .Size 属性) + # 先尝试 CSizeT().Size 模式(类型构造调用 + .Size 属性) size_val = ConstEvaluator._eval_ctype_size_attr(node) if size_val is not None: return size_val return ConstEvaluator._eval_attribute_define(node, symtab) - # 治本修复:支持 t.CUnsignedLong(-11) 等类型构造调用 + # 治本修复:支持 CUnsignedLong(-11) 等类型构造调用 if isinstance(node, ast.Call): return ConstEvaluator._eval_ctype_ctor_call(node, symtab) return ConstEvaluator._eval_arith(node, lambda n: ConstEvaluator.eval_with_symtab(n, symtab)) @staticmethod def _eval_ctype_ctor_call(node: ast.Call, symtab: Any) -> Optional[Any]: - """求值类型构造调用,如 t.CUnsignedLong(-11)、CInt(42)。 + """求值类型构造调用,如 CUnsignedLong(-11)、CInt(42)。 - 在无 ctx(EvalContext)的场景下,通过 symtab 和 t 模块直接求值。 + 在无 ctx(EvalContext)的场景下,通过 symtab 和 TypeSystem 直接求值。 按类型的 Size 和 IsSigned 应用位掩码。 """ func: ast.expr = node.func func_name: str | None = None - module_name: str | None = None - if isinstance(func, ast.Attribute): - if isinstance(func.value, ast.Name): - module_name = func.value.id - func_name = func.attr - elif isinstance(func, ast.Name): + if isinstance(func, ast.Name): func_name = func.id ctype_cls: Any = None - if module_name == 't' and func_name: - ctype_cls = getattr(_t_module, func_name, None) - elif func_name and not module_name: + if func_name: ctype_cls = getattr(_t_module, func_name, None) if ctype_cls is None and symtab: - t_type_syms = getattr(symtab, '_t_type_symbols', {}) + t_type_syms = getattr(symtab, '_builtin_type_symbols', {}) cls_candidate = t_type_syms.get(func_name) if cls_candidate is not None: ctype_cls = cls_candidate @@ -176,7 +169,7 @@ class ConstEvaluator: # Attribute — 查 define_constants / SymbolTable / 平台宏 if isinstance(node, ast.Attribute): - # 先尝试 t.CSizeT().Size 模式(类型构造调用 + .Size 属性) + # 先尝试 CSizeT().Size 模式(类型构造调用 + .Size 属性) size_val = ConstEvaluator._eval_ctype_size_attr(node) if size_val is not None: return size_val @@ -210,7 +203,7 @@ class ConstEvaluator: @staticmethod def _eval_compile_time_call(node: ast.Call, ctx: 'EvalContext') -> Optional[Any]: - """处理编译时函数调用,如 ctraits.isptr(x)、t.CUnsignedLong(-11)""" + """处理编译时函数调用,如 ctraits.isptr(x)、CUnsignedLong(-11)""" func: ast.expr = node.func func_name: str | None = None module_name: str | None = None @@ -222,7 +215,7 @@ class ConstEvaluator: elif isinstance(func, ast.Name): func_name = func.id - # c.@CIfdef(NAME) / c.@CIfndef(NAME):defined(NAME) 的解析期 desugar 标记,编译期返回 0/1。 + # @CIfdef(NAME) / @CIfndef(NAME):defined(NAME) 的解析期 desugar 标记,编译期返回 0/1。 # 仅出现在 cif/celif 条件内(解析器保证),故此处只做宏定义判定。 if func_name == '@CIfdef': if node.args: @@ -251,7 +244,7 @@ class ConstEvaluator: is_isptr = True elif func_name == 'isptr' and not module_name: # 检查是否通过 from ctraits import isptr 导入 - t_c_imported = getattr(ctx.translator, '_t_c_imported_names', {}) if ctx.translator else {} + t_c_imported = getattr(ctx.translator, '_from_import_aliases', {}) if ctx.translator else {} if func_name in t_c_imported: src_module, _ = t_c_imported[func_name] if src_module == 'ctraits': @@ -286,24 +279,19 @@ class ConstEvaluator: except Exception: return None - # 治本修复:支持 t.CUnsignedLong(-11) 等类型构造调用 - # 当 t.CUnsignedLong(value) / CUnsignedInt(value) / CInt(value) 等被用作常量表达式时, + # 治本修复:支持 CUnsignedLong(-11) 等类型构造调用 + # 当 CUnsignedLong(value) / CUnsignedInt(value) / CInt(value) 等被用作常量表达式时, # 求值参数并返回(按类型的无符号/有符号语义应用位掩码)。 - # 这修复了 stdint.py 中 INFINITE = t.CUnsignedLong(-1) 等常量无法被求值的问题。 + # 这修复了 stdint.py 中 INFINITE = CUnsignedLong(-1) 等常量无法被求值的问题。 is_ctype_ctor: bool = False ctype_cls: Any = None - if module_name == 't' and func_name: + if func_name and not module_name: ctype_cls = getattr(_t_module, func_name, None) if ctype_cls is not None and isinstance(ctype_cls, type) and issubclass(ctype_cls, _CType_base): is_ctype_ctor = True - elif func_name and not module_name: - # from t import CUnsignedLong 形式 - ctype_cls = getattr(_t_module, func_name, None) - if ctype_cls is not None and isinstance(ctype_cls, type) and issubclass(ctype_cls, _CType_base): - is_ctype_ctor = True - # 也检查 _t_type_symbols(符号表中的 t 模块类型符号) + # 也检查 _builtin_type_symbols(符号表中的内建类型符号) if not is_ctype_ctor and ctx.symtab: - t_type_syms = getattr(ctx.symtab, '_t_type_symbols', {}) + t_type_syms = getattr(ctx.symtab, '_builtin_type_symbols', {}) cls_candidate = t_type_syms.get(func_name) if cls_candidate is not None and isinstance(cls_candidate, type) and issubclass(cls_candidate, _CType_base): ctype_cls = cls_candidate @@ -418,10 +406,9 @@ class ConstEvaluator: @staticmethod def _eval_ctype_size_attr(node: ast.Attribute) -> Optional[int]: - """求值 t.CSizeT().Size 等类型构造调用 + .Size 属性模式。 + """求值 CSizeT().Size 等类型构造调用 + .Size 属性模式。 - 匹配 AST 形态: Attribute(attr='Size', value=Call(func=Attribute(value=Name(id='t'), attr='CSizeT'))) - 或直接 Call(func=Name(id='CSizeT'))(from t import CSizeT 后的使用方式)。 + 匹配 AST 形态: Attribute(attr='Size', value=Call(func=Name(id='CSizeT'))). 返回类型大小(位数),如 CSizeT().Size 返回 64(64 位平台)。 """ if node.attr != 'Size': @@ -433,15 +420,13 @@ class ConstEvaluator: return None func: ast.expr = call_node.func type_name: str | None = None - if isinstance(func, ast.Attribute) and isinstance(func.value, ast.Name) and func.value.id == 't': - type_name = func.attr - elif isinstance(func, ast.Name): + if isinstance(func, ast.Name): type_name = func.id if not type_name: return None # 延迟导入避免循环依赖 try: - from lib.includes.t import CTypeRegistry + from lib.core.TypeSystem import CTypeRegistry except Exception: return None cls = CTypeRegistry.GetClassByName(type_name) @@ -566,7 +551,7 @@ class EvalContext: return None def is_macro_defined(self, name: str) -> bool: - """判定宏 NAME 是否已定义(供 defined(NAME) / c.@CIfdef 标记使用)。 + """判定宏 NAME 是否已定义(供 defined(NAME) / @CIfdef 标记使用)。 来源与 HandlesIf._is_macro_defined 同口径:Gen._define_constants / _DefineConstants / SymbolTable.is_define / 平台宏。 diff --git a/lib/core/Handles/HandlesAnnAssign.py b/lib/core/Handles/HandlesAnnAssign.py index 36dc36f..64ce0ae 100644 --- a/lib/core/Handles/HandlesAnnAssign.py +++ b/lib/core/Handles/HandlesAnnAssign.py @@ -8,7 +8,7 @@ import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode -from lib.includes import t +from lib.core import TypeSystem from lib.core.SymbolUtils import ( IsListAnnotation, ParseListAnnotation, FindStructNameInAnnotationWithContext, AnnotationContainsName, IsCPtrNode, RequireDefineConstStorable, @@ -19,7 +19,7 @@ from lib.core.SymbolUtils import ( def _IsGenericTpName(name: str) -> bool: """判断名称是否为泛型类型参数(单字母大写,如 T/U/V) - 用于 _is_struct_ptr_union 判定:elem_ptr: T | t.CPtr = t.CPtr(...) + 用于 _is_struct_ptr_union 判定:elem_ptr: T | CPtr = CPtr(...) (_list.vp 泛型方法体,T 未解析)时按 8 字节指针槽处理,避免 var_struct_class 误注册 llvmlite.Value 后 elem_ptr[0] cast 到 Value* 与函数声明 i8* 不匹配(8fbba llc 报错根因)。标量 T(如 int)退化为 @@ -30,17 +30,17 @@ def _IsGenericTpName(name: str) -> bool: return len(name) == 1 and name.isalpha() and name.isupper() -# 指针/未知**占位**类名(非真实类):联合注解 rawptr[T] / X | t.CPtr 折叠后, +# 指针/未知**占位**类名(非真实类):联合注解 rawptr[T] / X | CPtr 折叠后, # var_struct_class 里可能落进这些占位名(它们可能恰好也在 Gen.structs 里,如 # 'rawptr')。占位名不表态具体类 ⇒ 不得登记为「注解声明类」的权威值,否则会挡住 -# "无注解赋值从右值推断类名"的正常路径(如 `p: t.CPtr = Point()` 之后 `p.x` 需要 +# "无注解赋值从右值推断类名"的正常路径(如 `p: CPtr = Point()` 之后 `p.x` 需要 # Point)。形态三种(见本文件 L753 的同类判据):裸 'rawptr'、带模块前缀 # 'sha1.rawptr'、下标式 'rawptr[X]';CPtr 一族的裸名/限定名同样计入。 _PTR_MARKER_CLASS_NAMES: frozenset[str] = frozenset({ - 'rawptr', 't.rawptr', 'c.rawptr', - 'CPtr', 't.CPtr', 'c.CPtr', - 'CAutoPtr', 't.CAutoPtr', - 'CRef', 't.CRef', 'CTempRef', 't.CTempRef', + 'rawptr', 'rawptr', + 'CPtr', 'CPtr', 'CPtr', + 'CAutoPtr', 'CAutoPtr', + 'CRef', 'CRef', 'CTempRef', 'CTempRef', }) @@ -291,7 +291,7 @@ class AnnAssignHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"隐式窄化禁止:{Value.type.width} 位整数不能隐式赋给 {TargetType.width} 位类型" - f"(会丢高位);请显式转换(如 int32(x) / t.CInt32T(x) )或把目标类型加宽" + f"(会丢高位);请显式转换(如 int32(x) / CInt32T(x) )或把目标类型加宽" f"{Gen._DescribeValueNode(Node)}" ) else: @@ -304,7 +304,7 @@ class AnnAssignHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转换已禁止({Reason}):不能把指针类型 {Value.type} 隐式转为 {TargetType};" - f"如需转换请显式 cast(如 t.CPtr(...))" + f"如需转换请显式 cast(如 CPtr(...))" f"{Gen._DescribeValueNode(Node)}" ) Value = Gen.builder.bitcast(Value, TargetType, name="ptr_bitcast") @@ -316,7 +316,7 @@ class AnnAssignHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:不能把指针类型 {Value.type} 赋给整数类型 {TargetType};" - f"如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{Gen._DescribeValueNode(Node)}" ) Gen._store(Value, Ptr) @@ -357,7 +357,7 @@ class AnnAssignHandle(BaseHandle): 2. alloca + __before_init__ + __new__(pool) + __before_init__ + __init__(pool) 3. 对每个元素调用 append(elem) 4. 将堆指针存入变量 - list_sub 是从注解中提取的 list[...] Subscript 节点(支持 list[T] 和 list[T] | t.CPtr) + list_sub 是从注解中提取的 list[...] Subscript 节点(支持 list[T] 和 list[T] | CPtr) """ # 1. 解析元素类型 slice_node: ast.expr = list_sub.slice @@ -461,10 +461,10 @@ class AnnAssignHandle(BaseHandle): Gen.builder.call(append_func, adjusted_append, name=f"append_{VarName}_{i}") # 10. 创建变量并存储堆指针 - # 判断变量类型:list[T] | t.CPtr → i8*;list[T] → Ptr(StructType) + # 判断变量类型:list[T] | CPtr → i8*;list[T] → Ptr(StructType) is_cptr_union: bool = isinstance(Node.annotation, ast.BinOp) and isinstance(Node.annotation.op, ast.BitOr) if is_cptr_union: - # list[T] | t.CPtr → 变量类型为 i8* + # list[T] | CPtr → 变量类型为 i8* i8_ptr_type: ir.PointerType = ir.PointerType(ir.IntType(8)) var: ir.AllocaInstr = Gen._allocaEntry(i8_ptr_type, name=VarName) # bitcast heap_ptr (Ptr(StructType)) → i8* @@ -502,9 +502,9 @@ class AnnAssignHandle(BaseHandle): _VarName: str = Node.target.id _DeclCls: str | None = Gen.var_struct_class.get(_VarName) # 只把**真实类名**记为权威:指针/未知标记名(rawptr/CPtr/... 这些是联合 - # 注解 `rawptr[T]`/`X | t.CPtr` 折叠后的占位名,可能恰好在 Gen.structs 里) + # 注解 `rawptr[T]`/`X | CPtr` 折叠后的占位名,可能恰好在 Gen.structs 里) # 不表态具体类,若一并记为权威会挡住"无注解赋值从右值推断类名"的正常路径 - # (如 `p: t.CPtr = Point()` 之后 `p.x` 需要 Point)。 + # (如 `p: CPtr = Point()` 之后 `p.x` 需要 Point)。 if _DeclCls and not _IsPtrMarkerClassName(_DeclCls): _M: dict = getattr(Gen, 'var_annotated_class', None) if _M is None: @@ -538,7 +538,7 @@ class AnnAssignHandle(BaseHandle): TypeInfo: CTypeInfo | None = self.Trans.TypeMergeHandler.GetCTypeInfo(Node.annotation) if TypeInfo is None: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CInt() + TypeInfo.BaseType = TypeSystem.CInt() IsPtr: bool = TypeInfo.IsPtr if TypeInfo.IsDefine: if Node.value and isinstance(Node.value, ast.Constant): @@ -555,7 +555,7 @@ class AnnAssignHandle(BaseHandle): self.Trans.SymbolTable.insert(VarName, info) Gen._record_var_signedness(VarName, TypeInfo.IsUInt) elif Node.value: - # 非 Constant 表达式:尝试编译期求值(如 t.CSizeT().Size // 8) + # 非 Constant 表达式:尝试编译期求值(如 CSizeT().Size // 8) from lib.core.ConstEvaluator import ConstEvaluator, EvalContext ctx = EvalContext(Gen=Gen, symtab=self.Trans.SymbolTable, translator=self.Trans) eval_val = ConstEvaluator.eval_full(Node.value, ctx) @@ -572,7 +572,7 @@ class AnnAssignHandle(BaseHandle): Gen._record_var_signedness(VarName, TypeInfo.IsUInt) return if TypeInfo.IsStr or (isinstance(Node.annotation, ast.Name) and Node.annotation.id == 'str'): - # 仅指针层数 <= 1 才算裸 str/bytes(i8*),可以压平:`str | t.CPtr` / + # 仅指针层数 <= 1 才算裸 str/bytes(i8*),可以压平:`str | CPtr` / # `str*` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 指针数组), # 压平会让局部变量比模块级同名全局槽少一层指针 # (全局走 HandlesAssign._EmitGlobalAnnAssignLlvm 的 FromNode,得到 i8**), @@ -581,19 +581,19 @@ class AnnAssignHandle(BaseHandle): # `IsStr and PtrCount <= 1` 同一条规则源。 if TypeInfo.PtrCount <= 1: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CChar() + TypeInfo.BaseType = TypeSystem.CChar() TypeInfo.PtrCount = 1 IsPtr = True # FakeDuck: 为 str 变量创建影子结构体 a__meta__ (栈上, per-instance) # a 保持为 char* 用于 printf; a__meta__ 存储 __data__ 和 __mbuddy__ 字段 - # 仅对 str 类型创建,bytes 和 t.CChar|t.CPtr 不创建 + # 仅对 str 类型创建,bytes 和 CChar|CPtr 不创建 if '_str' in Gen.structs and isinstance(Node.annotation, ast.Name) and Node.annotation.id == 'str': _meta_name: str = f"{VarName}__meta__" _meta_var: ir.AllocaInstr = Gen._allocaEntry(Gen.structs['_str'], name=_meta_name) Gen.variables[_meta_name] = _meta_var - # 标记指针到 str/bytes 的变量 (BinOp 注解如 str | t.CPtr) + # 标记指针到 str/bytes 的变量 (BinOp 注解如 str | CPtr) # elem_ptr[0] 应加载/存储 8 字节 (指针), 而非 1 字节 (字符) - # 仅当注解包含 str 或 bytes 时设置(t.CChar | t.CPtr 不应设置,它是纯字符指针) + # 仅当注解包含 str 或 bytes 时设置(CChar | CPtr 不应设置,它是纯字符指针) if isinstance(Node.annotation, ast.BinOp) and isinstance(Node.annotation.op, ast.BitOr): if AnnotationContainsName(Node.annotation, 'str') or AnnotationContainsName(Node.annotation, 'bytes'): Gen.var_ptr_element[VarName] = True @@ -608,7 +608,7 @@ class AnnAssignHandle(BaseHandle): ) if parse_result.is_pointer: # 单参数 list[type] → 指针 - # 但如果有列表字面量初始化值 [a, b, c],则按数组 t.CArray[type, N] 处理 + # 但如果有列表字面量初始化值 [a, b, c],则按数组 CArray[type, N] 处理 if not (Node.value and isinstance(Node.value, ast.List)): VarType: ir.Type = ir.PointerType(ElemType) var: ir.AllocaInstr = Gen._allocaEntry(VarType, name=VarName) @@ -652,7 +652,7 @@ class AnnAssignHandle(BaseHandle): return # list[T] 泛型类注解 + list 字面量值 → 构造 list[T] 对象 + append 序列 # (list[str] = ["a", "b"] 不应走 C 数组路径,而应构造 list[str] 对象) - # 支持两种注解形式:list[T] 和 list[T] | t.CPtr + # 支持两种注解形式:list[T] 和 list[T] | CPtr list_sub: ast.Subscript | None = None if (isinstance(Node.annotation, ast.Subscript) and isinstance(Node.annotation.value, ast.Name) @@ -676,8 +676,8 @@ class AnnAssignHandle(BaseHandle): return # Only fall back to the left operand when the union neither resolved a base # type nor accumulated multi-level pointers. A pointer-marker based union - # (`t.CPtr*` = `t.CPtr | t.CPtr` => CVoid/2) is already a fully resolved - # multi-level pointer; falling back to its left operand (`t.CPtr` => 1 layer) + # (`CPtr*` = `CPtr | CPtr` => CVoid/2) is already a fully resolved + # multi-level pointer; falling back to its left operand (`CPtr` => 1 layer) # used to silently degrade it to i8*. Keep PtrCount > 1 untouched. if (TypeInfo.IsVoid and TypeInfo.PtrCount <= 1 and isinstance(Node.annotation, ast.BinOp)): @@ -685,7 +685,7 @@ class AnnAssignHandle(BaseHandle): Node.annotation, self.Trans, Gen) if found: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CStruct(name=found) + TypeInfo.BaseType = TypeSystem.CStruct(name=found) TypeInfo.PtrCount = 1 IsPtr = True elif isinstance(Node.annotation.left, ast.Attribute): @@ -694,7 +694,7 @@ class AnnAssignHandle(BaseHandle): TypeInfo = AttrTypeInfo TypeInfo.PtrCount = max(TypeInfo.PtrCount, 1) IsPtr = True - # 对于局部变量声明 s: TestStruct(不带 | t.CPtr),应为栈上结构体而非指针 + # 对于局部变量声明 s: TestStruct(不带 | CPtr),应为栈上结构体而非指针 # GetCTypeInfo 默认设置 PtrCount=1,但纯结构体名注解应为值类型 if (isinstance(Node.annotation, ast.Name) and Node.annotation.id in Gen.structs @@ -724,7 +724,7 @@ class AnnAssignHandle(BaseHandle): if isinstance(VarType, ir.VoidType): VarType = ir.IntType(32) IsUnsigned: bool = TypeInfo.IsUInt - # 修复 3: BinOp 注解(如 ast.Arguments | t.CPtr)的 var_struct_class 设置 + # 修复 3: BinOp 注解(如 ast.Arguments | CPtr)的 var_struct_class 设置 # TypeInfo.Name 由 _HandleSubscript 设置(特化名如 list[sha1.ASTptr])或 # GetCTypeInfo 设置(普通结构体名),经 _MergeCTypeInfoInto 传播后保留。 # 此处确保 BinOp 注解的变量也能被 _get_var_class 识别,避免方法调用分派 @@ -734,7 +734,7 @@ class AnnAssignHandle(BaseHandle): if VarName not in Gen.var_struct_class: Gen.var_struct_class[VarName] = TypeInfo.Name Gen.global_struct_class[VarName] = TypeInfo.Name - # 联合指针注解(X | t.CPtr)短名回退:resolver 对模块限定 struct + # 联合指针注解(X | CPtr)短名回退:resolver 对模块限定 struct # 段(如 llvmlite.Value)无法精确 in Gen.structs(键可能是 'Value' # 或带 sha1 前缀),Name 常退化为指针别名 'rawptr'(被注册成 opaque # struct)→ 变量 var_struct_class 登记为 rawptr → 字段访问 @@ -744,7 +744,7 @@ class AnnAssignHandle(BaseHandle): and isinstance(Node.annotation.op, ast.BitOr)): _union_struct_name2: str | None = FindStructNameInAnnotationWithContext( Node.annotation, self.Trans, Gen) - # resolver 对模块限定 struct 联合(llvmlite.Value | t.CPtr)常给出 + # resolver 对模块限定 struct 联合(llvmlite.Value | CPtr)常给出 # 指针占位名(如 '{sha1}.rawptr')且该占位恰好注册在 Gen.structs, # 使上方 TypeInfo.Name in Gen.structs 通过并登记错误类名 → 字段 # 访问 "属性 'Next' 在类 'rawptr' 中找不到"。凡短名命中真实类 @@ -754,7 +754,7 @@ class AnnAssignHandle(BaseHandle): Gen.var_struct_class[VarName] = _union_struct_name2 if getattr(Gen, 'global_struct_class', None) is not None: Gen.global_struct_class[VarName] = _union_struct_name2 - # Subscript rawptr[X] / t.CPtr[X] 注解的本地结构指针变量(如 + # Subscript rawptr[X] / CPtr[X] 注解的本地结构指针变量(如 # includes/ast/parser.vp _fix_store_ctx 里 `tp: rawptr[Tuple] = # (rawptr[Tuple])(node)`,随后 `tp_elts = tp.elts`):TypeMerge 的 # builtins 分支把 rawptr[X] 折叠为 i8*(PtrCount=1/CVoid),既不登记 @@ -771,7 +771,7 @@ class AnnAssignHandle(BaseHandle): _rst_nm = _rst_v.id elif isinstance(_rst_v, ast.Attribute) and isinstance(_rst_v.value, ast.Name): _rst_nm = f'{_rst_v.value.id}.{_rst_v.attr}' - if _rst_nm in ('rawptr', 't.CPtr'): + if _rst_nm in ('rawptr', 'CPtr'): _rst_sub = Node.annotation if _rst_sub is not None: _rst_sl: ast.AST = _rst_sub.slice @@ -804,19 +804,17 @@ class AnnAssignHandle(BaseHandle): Gen.var_struct_class[VarName] = _rst_tk if getattr(Gen, 'global_struct_class', None) is not None: Gen.global_struct_class[VarName] = _rst_tk - # 检测指针到指针缓冲区变量:注解为 StructName | t.CPtr,且赋值来自 t.CPtr(...) 调用。 - # 这种变量(如 list[T].__getitem__ 中的 elem_ptr: T | t.CPtr = t.CPtr(...)) - # 实际指向存储结构体指针的缓冲区(T=AST|t.CPtr 时特化为 AST*,缓冲区存 AST* 数组)。 + # 检测指针到指针缓冲区变量:注解为 StructName | CPtr,且赋值来自 CPtr(...) 调用。 + # 这种变量(如 list[T].__getitem__ 中的 elem_ptr: T | CPtr = CPtr(...)) + # 实际指向存储结构体指针的缓冲区(T=AST|CPtr 时特化为 AST*,缓冲区存 AST* 数组)。 # [index] 应 bitcast 为 AST** 后 GEP 指针数组再 load,而非 GEP 结构体数组。 - # 泛型特化将 T|t.CPtr 降级为 StructName|t.CPtr(丢失一层指针),故通过赋值来源区分: - # elem_ptr 的值是 t.CPtr(buf + idx*elem_size)(原始指针运算,缓冲区内容未知), - # pts 的值是 (Point|t.CPtr)(...)(类型转换,明确指向 Point 结构体)。 + # 泛型特化将 T|CPtr 降级为 StructName|CPtr(丢失一层指针),故通过赋值来源区分: + # elem_ptr 的值是 CPtr(buf + idx*elem_size)(原始指针运算,缓冲区内容未知), + # pts 的值是 (Point|CPtr)(...)(类型转换,明确指向 Point 结构体)。 _is_cptr_assign: bool = ( isinstance(Node.value, ast.Call) - and isinstance(Node.value.func, ast.Attribute) - and isinstance(Node.value.func.value, ast.Name) - and Node.value.func.value.id == 't' - and Node.value.func.attr == 'CPtr' + and isinstance(Node.value.func, ast.Name) + and Node.value.func.id == 'CPtr' ) _is_struct_ptr_union: bool = ( isinstance(Node.annotation, ast.BinOp) @@ -932,9 +930,9 @@ class AnnAssignHandle(BaseHandle): var: ir.AllocaInstr = Gen._allocaEntry(VarType, name=VarName) if InitValue and isinstance(InitValue.type, ir.PointerType): pointee: ir.Type = InitValue.type.pointee - # 当 InitValue 是 i8* (t.CPtr) 且注解是 Gen.structs 中的结构体名时, + # 当 InitValue 是 i8* (CPtr) 且注解是 Gen.structs 中的结构体名时, # bitcast 为对应的结构体指针,以便正确存储和设置 var_struct_class - # 例如: sub: dict = sub_p (sub_p 是 t.CPtr) + # 例如: sub: dict = sub_p (sub_p 是 CPtr) if (isinstance(pointee, ir.IntType) and pointee.width == 8 and isinstance(Node.annotation, ast.Name) and Node.annotation.id in Gen.structs): @@ -961,10 +959,10 @@ class AnnAssignHandle(BaseHandle): Gen.global_struct_class[VarName] = Node.annotation.id Gen._record_var_signedness(VarName, IsUnsigned) return - # 方向判定用:取注解一侧的泛型基名(`Base[...]` 或 `Base[...] | t.CPtr` + # 方向判定用:取注解一侧的泛型基名(`Base[...]` 或 `Base[...] | CPtr` # 形态中的 Base)。此判据**不依赖泛型模板注册表**(list/dict 等内建 # 容器可能未登记),只做结构性识别;仅 Name 形态可识别,属性链 - # (如 t.CPtr[...])不参与。 + # (如 CPtr[...])不参与。 _ann_gen_base: str | None = None _ann_sub_side: ast.expr | None = None if isinstance(Node.annotation, ast.Subscript): @@ -983,7 +981,7 @@ class AnnAssignHandle(BaseHandle): if isinstance(_ann_base_v, ast.Name): _ann_gen_base = _ann_base_v.id # 「反向重建」方向判定(其二,见下方 _rb_is_upcast)所需的**注解侧 - # 被指类**:注解被 TypeMerge 折叠成 i8*(rawptr[X] / t.CPtr[X],见 + # 被指类**:注解被 TypeMerge 折叠成 i8*(rawptr[X] / CPtr[X],见 # 上方 635-684)时 VarType.pointee 不是结构体,此时用该处恢复进 # var_struct_class 的 X —— 那正是注解写明的被指类。 _ann_pointee: ir.Type | None = None @@ -1006,13 +1004,13 @@ class AnnAssignHandle(BaseHandle): if _IsGenericTpName(_cn_short): continue # rawptr 占位 struct('rawptr' / '{sha1}.rawptr' / 'rawptr[...]')是 - # 模块限定联合 X | t.CPtr 被 resolver 退化的产物(无真实字段), + # 模块限定联合 X | CPtr 被 resolver 退化的产物(无真实字段), # 绝不能覆盖注解已解析出的真实类名(如 Value)→ env_size_val.Next # 报 "属性在类 'rawptr' 中找不到"(FuncGenMixin.vp L307 根因)。 if CN == 'rawptr' or CN.endswith('.rawptr') or CN.startswith('rawptr['): continue if pointee is ST or pointee == ST: - # 若注解是泛型特化(如 ndarray[t.CDouble] | t.CPtr), + # 若注解是泛型特化(如 ndarray[CDouble] | CPtr), # 构造正确的特化名(如 ndarray[double]),而非用 opaque 基础名 resolved_cn: str = CN if isinstance(Node.annotation, ast.BinOp) and isinstance(Node.annotation.op, ast.BitOr) and '[' not in CN: @@ -1041,7 +1039,7 @@ class AnnAssignHandle(BaseHandle): # RHS 构造出精确特化 ⇒ 用 RHS 反向升级」(见 L765 注释)。 # 但 RHS 的 pointee 若为**裸泛型基类**(丢类型实参,如 # {sha1}.list)而注解一侧本身就是带类型实参的泛型 - # (`Base[...]` 或 `Base[...] | t.CPtr`),以 RHS 重建 + # (`Base[...]` 或 `Base[...] | CPtr`),以 RHS 重建 # alloca 会把注解已解析出的特化类型覆盖成裸基类 → 之后 # .get() 按错误元素类型分派(list[int].get 返回 i32)→ # inttoptr 截断指针 → 读垃圾 AST 节点崩溃 @@ -1098,7 +1096,7 @@ class AnnAssignHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转换已禁止({Reason}):不能用指针类型 {InitValue.type} 初始化 " - f"{VarName}: {VarType};如需转换请显式 cast(如 t.CPtr(...))" + f"{VarName}: {VarType};如需转换请显式 cast(如 CPtr(...))" f"{Gen._DescribeValueNode(Node.value)}" ) InitValue = Gen.builder.bitcast(InitValue, VarType, name=f"cast_{VarName}") @@ -1110,7 +1108,7 @@ class AnnAssignHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:不能用指针类型 {InitValue.type} 初始化整数变量 " - f"{VarName}: {VarType};如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"{VarName}: {VarType};如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{Gen._DescribeValueNode(Node.value)}" ) # 大端局部变量:存储时 bswap @@ -1150,7 +1148,7 @@ class AnnAssignHandle(BaseHandle): found_struct: str | None = FindStructNameInAnnotationWithContext( Node.annotation, self.Trans, Gen) # 若 FindStructNameInAnnotation 仅返回裸模板名(如 'ndarray'),但注解中 - # 含泛型特化(如 numpy.ndarray[t.CDouble]),用 LLVM 类型名构造特化名 + # 含泛型特化(如 numpy.ndarray[CDouble]),用 LLVM 类型名构造特化名 # (如 'ndarray[double]')。main.py 的 Gen.structs 可能只有 opaque 'ndarray', # 但 numpy 模块已特化 ndarray[double],方法调用通过 sha1 前缀查找。 if found_struct and '[' not in found_struct: @@ -1196,7 +1194,7 @@ class AnnAssignHandle(BaseHandle): self.Trans.VarScopes[-1][VarName] = TypeInfo else: DefaultInfo: CTypeInfo = CTypeInfo() - DefaultInfo.BaseType = t.CInt + DefaultInfo.BaseType = TypeSystem.CInt self.Trans.VarScopes[-1][VarName] = DefaultInfo elif isinstance(Node.target, ast.Attribute): if isinstance(Node.target.value, ast.Name) and Node.target.value.id == 'self': @@ -1206,16 +1204,16 @@ class AnnAssignHandle(BaseHandle): if IsListAnnotation(Node.annotation): slice_node: ast.AST = Node.annotation.slice if isinstance(slice_node, ast.Name): - AttrVarType = f't.CArray[{slice_node.id}]' + AttrVarType = f'CArray[{slice_node.id}]' elif isinstance(slice_node, ast.Tuple): elts: str = ', '.join(getattr(e, 'id', str(e)) for e in slice_node.elts) - AttrVarType = f't.CArray[{elts}]' + AttrVarType = f'CArray[{elts}]' elif isinstance(slice_node, ast.Attribute): - # 还原 t.xxx 形式(如 t.CInt、t.CArray) + # 还原模块限定类型名(如 ns.CInt) if isinstance(slice_node.value, ast.Name): - AttrVarType = f't.CArray[{slice_node.value.id}.{slice_node.attr}]' + AttrVarType = f'CArray[{slice_node.value.id}.{slice_node.attr}]' else: - AttrVarType = f't.CArray[{ast.unparse(slice_node)}]' + AttrVarType = f'CArray[{ast.unparse(slice_node)}]' if AttrVarType is None: AttrTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(Node.annotation, self.Trans.SymbolTable) if AttrTypeInfo: diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index 2fcea12..31e2b13 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -9,9 +9,9 @@ from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta from lib.core.VLogger import get_logger as _vlog from lib.core.ConstEvaluator import ConstEvaluator, EvalContext from lib.constants.config import mode as _config_mode -from lib.includes import t -from lib.includes.t import CTypeRegistry -from lib.core.SymbolUtils import IsTModule, ParseListAnnotation, AnnotationContainsName +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry +from lib.core.SymbolUtils import ParseListAnnotation, AnnotationContainsName class AssignHandle(BaseHandle): def __init__(self, translator: "Translator") -> None: @@ -62,7 +62,7 @@ class AssignHandle(BaseHandle): if Gen._IsVarConst(VarName): _vlog().error(Gen._ConstAssignMessage("赋值", VarName)) sys.exit(1) - if isinstance(Node.value, ast.Attribute) and isinstance(Node.value.value, ast.Name) and IsTModule(Node.value.value.id, self.Trans.SymbolTable): + if isinstance(Node.value, ast.Attribute) and isinstance(Node.value.value, ast.Name) : AttrName: str = Node.value.attr Gen.var_type_info[VarName] = {'type': 't_type', 'name': AttrName} Gen.var_type_assignments.setdefault(VarName, []).append({'type': 't_type', 'name': AttrName}) @@ -201,7 +201,7 @@ class AssignHandle(BaseHandle): # 【右值形态判定】只有"取地址形态"的右值才需要自动解一层引用:Name/Attribute/ # Subscript 的求值结果是**存储地址**(变量 alloca / 字段地址 /"对象即指针"), # 赋给指针变量时必须 load 出内层指针。而 Call(显式 cast 如 `str*(addr)`、 - # `t.CPtr(x)`,以及构造/普通函数调用)与其它表达式给出的是**值本身**, + # `CPtr(x)`,以及构造/普通函数调用)与其它表达式给出的是**值本身**, # 再 load 会多解一层 → 静默取到野指针(现场 includes/argparse.vp 的 # `entry = str*(uint64(argv) + idx*8)`:i8** 右值被多解一次,entry 变成 # argv[idx] 本身,随后 entry[0] 去读字符串头 8 字节 → ASan access-violation)。 @@ -312,7 +312,7 @@ class AssignHandle(BaseHandle): # 【联合返回注解的被指类恢复】RHS 是调用、且值的 LLVM 类型是**通用指针** # (i8*/i8**,pointee 不是结构体)时,上面那块类名推断整块失效 —— 现场 # `parts = s1.split(',')`:`split` 的返回注解 `list[str]*` ≡ - # `list[str] | t.CPtr`(只读探针确认二者 AST 逐字同形)被映射成 i8* + # `list[str] | CPtr`(只读探针确认二者 AST 逐字同形)被映射成 i8* # ⇒ 类名丢失 ⇒ 随后 `parts[0]` 不走 `list[str].__getitem__` 而按通用 # 指针/字节索引 ⇒ 得到整数 ⇒ 赋给 `str` 时报"整数隐式转指针已禁止" # (真因在 4 行之前,报文完全指不到)。此处从被调者的**返回注解** @@ -586,7 +586,7 @@ class AssignHandle(BaseHandle): f"解引用赋值 '*' 的操作数必须是指针类型(类型推断退化," f"实际 {Ptr.type}){Gen._get_node_info()}" ) - # `*a = *b` is the c.Load form: copy the raw bytes (width = target + # `*a = *b` is the Load form: copy the raw bytes (width = target # pointee), never convert the value. Without it a bit-pun such as # `*&bits = *&dbl` degrades to fptosi/trunc and loses the IEEE bits. if isinstance(Node.value, ast.UnaryOp) and isinstance(Node.value.op, ast.Deref): @@ -642,10 +642,10 @@ class AssignHandle(BaseHandle): if FuncDef.decorator_list: for decorator in FuncDef.decorator_list: if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute): - # fail-fast:`@c.CReturn` 已移除,扫到即报错。 + # fail-fast:`@CReturn` 已移除,扫到即报错。 if decorator.func.attr == 'CReturn': raise SyntaxError( - f"函数 '{FuncName}':`@c.CReturn` 已移除:请改用返回注解 " + f"函数 '{FuncName}':`@CReturn` 已移除:请改用返回注解 " f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)" f"{Gen._get_node_info()}" ) @@ -772,7 +772,7 @@ class AssignHandle(BaseHandle): ReturnTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(MultiRetTypes[j], self.Trans.SymbolTable) if ReturnTypeInfo is None: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() VarType = Gen._ctype_to_llvm(ReturnTypeInfo) elif ret_type and isinstance(ret_type, ir.LiteralStructType) and j < len(ret_type.elements): VarType = ret_type.elements[j] @@ -1265,7 +1265,7 @@ class AssignHandle(BaseHandle): # 同一套 `_DescribeMemberSlot`):槽类型的两条独立来源 # (class_members 声明侧 / struct body 布局侧)不一致时,值会被 # 写进类型完全不同的槽(现场:`self.Gen.TypeGenCType. - # LastBuiltinsTypedefResult = "t.CPtr"` 落到 i32 槽 → 指针隐式 + # LastBuiltinsTypedefResult = "CPtr"` 落到 i32 槽 → 指针隐式 # 转整数 fail-fast);报文里逐项列出两侧数据即可直接判定谁退化 # (此处目标形态是 `对象.字段 = 值`,Base 侧同理取 ObjVal 所指布局)。 try: @@ -1367,15 +1367,13 @@ class AssignHandle(BaseHandle): self._StoreWithCoerce(Value, MemberPtr) return elif isinstance(Target.value, ast.Call): - # Check if this is c.Deref(...) — we need the pointer, not the Loaded value + # Check if this is Deref(...) — we need the pointer, not the Loaded value ObjVal: ir.Value | None = None - is_cderef: bool = (isinstance(Target.value.func, ast.Attribute) and - isinstance(Target.value.func.value, ast.Name) and - Target.value.func.value.id == 'c' and - Target.value.func.attr == 'Deref' and + is_cderef: bool = (isinstance(Target.value.func, ast.Name) and + Target.value.func.id == 'Deref' and Target.value.args) if is_cderef: - # Get the pointer from c.Deref argument, don't Load the value + # Get the pointer from Deref argument, don't Load the value deref_arg: ast.expr = Target.value.args[0] inner_val: ir.Value | None = self.HandleExprLlvm(deref_arg) if inner_val and isinstance(inner_val.type, ir.PointerType): @@ -1481,7 +1479,7 @@ class AssignHandle(BaseHandle): obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.value) idx_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(Target.slice) if obj_val and idx_val: - # 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8 + # 处理 obj_val 为 i8(整数)的情况:联合类型 | CPtr 降级后可能被 load 为 i8 if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8: obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}") if BaseHandle._is_char_pointer(obj_val): @@ -1497,7 +1495,7 @@ class AssignHandle(BaseHandle): IndexVal: ir.Value | None = self.HandleExprLlvm(Target.slice) if not ValueVal or not IndexVal: return - # 当变量本身是二级指针(如 elem_ptr: T | t.CPtr = AST**), + # 当变量本身是二级指针(如 elem_ptr: T | CPtr = AST**), # 且存储的值也是指针时,elem_ptr[i] = item 应直接存储指针(8 字节), # 而非解引用后复制结构体(如 48 字节的 AST),避免对象切片 if isinstance(Target.value, ast.Name): @@ -1552,7 +1550,7 @@ class AssignHandle(BaseHandle): and isinstance(Target.value, ast.Name) and (Gen.var_ptr_element.get(Target.value.id, False) or Gen.global_var_ptr_element.get(Target.value.id, False))): - # 指针到 str/bytes 的变量 (BinOp 注解如 str | t.CPtr) + # 指针到 str/bytes 的变量 (BinOp 注解如 str | CPtr) # elem_ptr 是 i8* 但实际指向 i8* (字符串指针), elem_ptr[0] = item 应存储 8 字节 CastedPtrPtr: ir.Value = Gen.builder.bitcast(ValueVal, ir.PointerType(ir.PointerType(ir.IntType(8))), name="cast_pp_str_store") if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64: @@ -1564,7 +1562,7 @@ class AssignHandle(BaseHandle): ElemPtr: ir.Value = Gen.builder.gep(ValueVal, [IndexVal], name=f"subscript{_PVSuffix}") # fail-fast:rawptr[T](基座是指针存储)的元素为对象 T、而 RHS 是指向 T # 的指针时,下游 _StoreWithCoerce/_coerce_value 会静默 load 整对象再按 - # sizeof(T) 存储(写 sizeof(T) 而非 8 字节指针)。数组槽(t.CArray[T,N]) + # sizeof(T) 存储(写 sizeof(T) 而非 8 字节指针)。数组槽(CArray[T,N]) # 本就按 sizeof(T) 布局,整对象赋值合法 ⇒ 由 IsArrayBase 排除。 self._RejectWholeObjectCopyIntoPtrSlot( Target, Value, ElemPtr, isinstance(pointee, ir.ArrayType)) @@ -1639,10 +1637,10 @@ class AssignHandle(BaseHandle): # 越界 sizeof(T)-8 字节,写穿相邻块(MemBuddy 空闲链表被写穿的静默降级根因)。 # # 不拦(判据刻意收窄,避免误伤): - # · 数组槽 t.CArray[T,N](IsArrayBase=True):元素槽本就按 sizeof(T) 布局, + # · 数组槽 CArray[T,N](IsArrayBase=True):元素槽本就按 sizeof(T) 布局, # `v[i] = T(...)`(构造函数返回临时对象地址)是合法的整对象复制; # · 元素是标量(rawptr[int]):ElemPtr 元素不是结构体; - # · 元素本身是指针(rawptr[rawptr[T]] / X|t.CPtr):元素类型是 Ptr; + # · 元素本身是指针(rawptr[rawptr[T]] / X|CPtr):元素类型是 Ptr; # · RHS 所指类型与元素类型不一致(非本形态)。 # 与 VPC AssignGenMixin._reject_whole_object_copy_into_ptr_slot 同口径。 # ============================================================ @@ -1682,8 +1680,8 @@ class AssignHandle(BaseHandle): f"而不是按指针写 {PtrSize} 字节。若该地址实际按 8 字节槽存放指针" f"(如 rawptr[T] 缓冲/空闲链表),每写一个元素就越界 {Over} 字节," f"直接写穿相邻块。修法:把指针槽的基座类型写成指针元素形态" - f"(`rawptr[T] | t.CPtr` 或 `rawptr[rawptr[T]]`)后再赋值;" - f"或把基座显式转为 t.CPtr(无类型指针)后按 8 字节指针语义写入。{SrcInfo}") + f"(`rawptr[T] | CPtr` 或 `rawptr[rawptr[T]]`)后再赋值;" + f"或把基座显式转为 CPtr(无类型指针)后按 8 字节指针语义写入。{SrcInfo}") def _DescribeMemberSlot(self, Gen: "Translator.LlvmGen", ClassName: str | None, FieldName: str, Offset: int, SelfPtr: ir.Value, @@ -1785,7 +1783,7 @@ class AssignHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转换已禁止({Reason}):不能把指针类型 {Value.type} 隐式转为 {TargetType};" - f"如需转换请显式 cast(如 t.CPtr(...))" + f"如需转换请显式 cast(如 CPtr(...))" f"{Gen._DescribeValueNode(Node)}" ) Value = Gen.builder.bitcast(Value, TargetType, name="ptr_bitcast") @@ -1842,11 +1840,10 @@ class AssignHandle(BaseHandle): if Info: if Info.IsTypedef: return - # 模块级全局 t.attr.* 属性(注解联合形态 `T | t.attr.section("...")`): + # 模块级全局 attr.* 属性(注解联合形态 `T | attr.section("...")`): # 先解析(空/缺段名、非正整数字面量 aligned → fail-fast 终止),再在各 - # 全局创建点用 _ApplyGlobalAttrs 施加。此前 TPC 全局路径完全没有 - # section/align/weak 代码(函数侧 section 只来自装饰器,见 - # HandlesFunctions.py:1361-1362 → :1767)。 + # 全局创建点用 _ApplyGlobalAttrs 施加。函数侧 section 只来自装饰器 + # (见 HandlesFunctions.py:1361-1362 → :1767)。 GlobalAttrs: dict[str, Any] = self._ExtractGlobalAttrs(Node, Gen) parse_result = ParseListAnnotation(Node.annotation) if parse_result: @@ -1856,7 +1853,7 @@ class AssignHandle(BaseHandle): check_func_ptr=True, void_fallback_width=32, fallback_to_cint=True, ) if parse_result.is_pointer: - # 单参数 t.CArray[T]:与 t.CArray[T, None] 统一为"长度自动推导数组"。 + # 单参数 CArray[T]:与 CArray[T, None] 统一为"长度自动推导数组"。 # 有可推导初值(列表字面量 / 字符串字面量)时不再生成裸指针,而是落入 # 下方数组路径:由 ParseArrayCount(count_node=None) 从字面量推导长度、 # 字节内联到变量自身(与类成员 DeclarationGenerator.py:775-784、 @@ -1932,9 +1929,9 @@ class AssignHandle(BaseHandle): TypeInfo: CTypeInfo | None = CTypeInfo.FromNode(Node.annotation, self.Trans.SymbolTable) IsCDefine: bool = False if TypeInfo and TypeInfo.BaseType: - if isinstance(TypeInfo.BaseType, t._CTypedef): + if isinstance(TypeInfo.BaseType, TypeSystem._CTypedef): return - if isinstance(TypeInfo.BaseType, t.CDefine): + if isinstance(TypeInfo.BaseType, TypeSystem.CDefine): IsCDefine = True if not IsCDefine and self._IsTypedefAnnotation(Node.annotation): IsCDefine = True @@ -1956,11 +1953,11 @@ class AssignHandle(BaseHandle): return if TypeInfo is None: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CInt() + TypeInfo.BaseType = TypeSystem.CInt() VarType: ir.Type = Gen._ctype_to_llvm(TypeInfo) if isinstance(VarType, ir.VoidType): VarType = ir.IntType(32) - # t.State 标记的模块级全局(`extern 名字: 类型` 的展开产物,见 + # State 标记的模块级全局(`extern 名字: 类型` 的展开产物,见 # SymbolUtils._ExpandExportExternVar):**只声明不定义**(external linkage), # 符号定义在外部(C 库 / 汇编 / 其它翻译单元),本模块不得再生成定义 # (否则 ld.lld duplicate symbol)。与 import 侧 @@ -1976,7 +1973,7 @@ class AssignHandle(BaseHandle): return # const / volatile 模块级全局登记(统一登记入口,持久层 global_*)。 # 局限(明确记录,见 Debugger/type-descriptors.md 已知差异):本分支只覆盖 - # 标量/指针型全局;数组(t.CArray[...])与结构体型全局在更早的分支 + # 标量/指针型全局;数组(CArray[...])与结构体型全局在更早的分支 # (上方 1568-1627)已 return,不在此登记 —— 全仓普查无这类带 const/ # volatile 注解的全局,故无可观测差异。 Gen.RegisterVarQualifiers(VarName, TypeInfo, Node.annotation, IsGlobal=True) @@ -2032,7 +2029,7 @@ class AssignHandle(BaseHandle): Gen.global_struct_class[VarName] = TypeInfo.Name return GlobalVar: ir.GlobalVariable = ir.GlobalVariable(Gen.module, VarType, name=VarName) - # 全局变量指针元素标志:bytes|t.CPtr 或 str|t.CPtr 注解的变量, + # 全局变量指针元素标志:bytes|CPtr 或 str|CPtr 注解的变量, # 使 var[index] 使用 8 字节指针步长(而非 1 字节字符步长) if isinstance(Node.annotation, ast.BinOp) and isinstance(Node.annotation.op, ast.BitOr): if AnnotationContainsName(Node.annotation, 'str') or AnnotationContainsName(Node.annotation, 'bytes'): @@ -2051,7 +2048,7 @@ class AssignHandle(BaseHandle): GlobalVar.initializer = self._BuildStringPtrInitializer(Gen, VarName, Node.value.value) Gen.variables[VarName] = GlobalVar elif isinstance(VarType, ir.PointerType) and isinstance(VarType.pointee, ir.FunctionType) and isinstance(Node.value, ast.Name): - # 函数指针赋值:f3: t.Callable[[int], int] = f + # 函数指针赋值:f3: Callable[[int], int] = f RefName: str = Node.value.id SymInfo: Any = self.Trans.SymbolTable.lookup(RefName) if SymInfo and (SymInfo.IsFunction or SymInfo.IsFuncPtr): @@ -2079,7 +2076,7 @@ class AssignHandle(BaseHandle): if init_val: GlobalVar.initializer = init_val elif isinstance(VarType, ir.BaseStructType) or (isinstance(Node.value, ast.Constant) and Node.value.value is None): - # None 初值全局(如各 Handles 模块的 _g_gen: t.CVoid|t.CPtr = None): + # None 初值全局(如各 Handles 模块的 _g_gen: CVoid|CPtr = None): # 多模块同名定义用 common linkage 让链接器合并(避免 # ld.lld duplicate symbol)。common 无 initializer,合并为零值, # 符合 None(=null) 语义。 @@ -2097,17 +2094,16 @@ class AssignHandle(BaseHandle): Gen.variables[VarName] = GlobalVar # ====================================================================== - # 模块级全局的 t.attr.* 属性(注解联合形态 `T | t.attr.section("...")`) + # 模块级全局的 attr.* 属性(注解联合形态 `T | attr.section("...")`) # - # 镜像 ViperC(Viper 自举侧)已有实现: + # 与 ViperC(Viper 自举侧)实现对应: # TranslatorGenMixin._scan_global_tattr / _extract_global_attr_section / # _extract_global_attr_aligned / _extract_global_attr_weak(.vp:590-651) # + ClassGenBase._tattr_name(.vp:341-358)+ _class_has_tattr 的 - # `c.Attribute(t.attr.xxx)` 解包(.vp:359-394)。 - # TPC(Python 侧)此前完全没有全局 section/align/weak 代码。 + # `Attribute(attr.xxx)` 解包(.vp:359-394)。 # ====================================================================== def _TAttrName(self, node: ast.AST | None) -> str | None: - """从 t.attr. / t.attr.(args) 节点提取最外层属性名。 + """从 attr. / attr.(args) 节点提取最外层属性名。 对应 ViperC ClassGenBase._tattr_name:Call → 递归取 func; Attribute → 取 attr。 @@ -2119,12 +2115,12 @@ class AssignHandle(BaseHandle): return None def _ScanGlobalTAttr(self, node: ast.AST | None, want_name: str) -> ast.AST | None: - """在全局变量注解中查找 t.attr. 节点,命中返回该节点。 + """在全局变量注解中查找 attr. 节点,命中返回该节点。 注解形态是 BinOp(BitOr) 左深链(`A | B | C` = BinOp(BinOp(A,B),C)), - 递归左右子节点。命中节点形态:Call(t.attr.aligned(16))或 - Attribute(t.attr.weak)。同时兼容包装写法 - `T | c.Attribute(t.attr.section("..."))`(解包参考 ViperC + 递归左右子节点。命中节点形态:Call(attr.aligned(16))或 + Attribute(attr.weak)。同时兼容包装写法 + `T | Attribute(attr.section("..."))`(解包参考 ViperC ClassGenBase._class_has_tattr,.vp:375-389)。 """ if node is None: @@ -2134,12 +2130,10 @@ class AssignHandle(BaseHandle): if hit_left is not None: return hit_left return self._ScanGlobalTAttr(node.right, want_name) - # 包装写法:c.Attribute(t.attr.xxx / t.attr.xxx(...)) → 拆 args 再扫 - # (与 HandlesFunctions.py:1354 装饰器侧同一判据:func.attr=='Attribute' - # 且 func.value 为 Name('c')) - if (isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) - and node.func.attr == 'Attribute' - and isinstance(node.func.value, ast.Name) and node.func.value.id == 'c'): + # 包装写法:Attribute(attr.xxx / attr.xxx(...)) → 拆 args 再扫 + # (与 HandlesFunctions.py 装饰器侧同一判据:func.id == 'Attribute') + if (isinstance(node, ast.Call) and isinstance(node.func, ast.Name) + and node.func.id == 'Attribute'): for arg in node.args: hit_arg: ast.AST | None = self._ScanGlobalTAttr(arg, want_name) if hit_arg is not None: @@ -2151,7 +2145,7 @@ class AssignHandle(BaseHandle): @staticmethod def _TAttrArgStr(node: ast.AST | None) -> str | None: - """取 t.attr.("...") 的字符串字面量参数(缺参/非字面量返回 None)。""" + """取 attr.("...") 的字符串字面量参数(缺参/非字面量返回 None)。""" if isinstance(node, ast.Call) and node.args: arg0: ast.AST = node.args[0] if isinstance(arg0, ast.Constant) and isinstance(arg0.value, str): @@ -2160,7 +2154,7 @@ class AssignHandle(BaseHandle): @staticmethod def _TAttrAlignInt(node: ast.AST | None) -> int | None: - """取 t.attr.aligned(N) 的整数字面量 N(缺参/非字面量返回 None)。 + """取 attr.aligned(N) 的整数字面量 N(缺参/非字面量返回 None)。 对应 ViperC ClassGenBase._tattr_aligned_int(.vp:395-415)。 """ @@ -2172,7 +2166,7 @@ class AssignHandle(BaseHandle): return None def _RaiseGlobalAttrError(self, Msg: str, Node: ast.AST, Gen: "Translator.LlvmGen", VarName: str) -> None: - """fail-fast:全局 t.attr.* 属性非法(缺/空段名、非正整数字面量 aligned)。 + """fail-fast:全局 attr.* 属性非法(缺/空段名、非正整数字面量 aligned)。 定位串(文件:行:列)与报错出口对齐 HandlesBase._RaiseUnresolvedExpr (HandlesBase.py:552-615)——错误信息含源码位置后 sys.exit(1)。 @@ -2195,7 +2189,7 @@ class AssignHandle(BaseHandle): sys.exit(1) def _ExtractGlobalAttrs(self, Node: ast.AnnAssign, Gen: "Translator.LlvmGen") -> dict[str, Any]: - """从模块级全局注解提取 t.attr.section/aligned/weak。 + """从模块级全局注解提取 attr.section/aligned/weak。 返回 {'section': str|None, 'align': int, 'weak': bool}。 非法值(空/缺段名、非正整数 aligned)→ fail-fast 终止(对齐 ViperC @@ -2209,7 +2203,7 @@ class AssignHandle(BaseHandle): sec_val: str | None = self._TAttrArgStr(sec_node) if not sec_val: self._RaiseGlobalAttrError( - "t.attr.section(...) 段名缺失或为空(空段名会生成非法的 section \"\")", + "attr.section(...) 段名缺失或为空(空段名会生成非法的 section \"\")", sec_node, Gen, VarName) Attrs['section'] = sec_val align_node: ast.AST | None = self._ScanGlobalTAttr(Ann, 'aligned') @@ -2217,7 +2211,7 @@ class AssignHandle(BaseHandle): align_val: int | None = self._TAttrAlignInt(align_node) if align_val is None or align_val <= 0: self._RaiseGlobalAttrError( - "t.attr.aligned(N) 需要正整数字面量 N", align_node, Gen, VarName) + "attr.aligned(N) 需要正整数字面量 N", align_node, Gen, VarName) Attrs['align'] = align_val if self._ScanGlobalTAttr(Ann, 'weak') is not None: Attrs['weak'] = True @@ -2261,7 +2255,7 @@ class AssignHandle(BaseHandle): return ir.Constant(var_type, int(value_node.value)) elif isinstance(value_node.value, str): return None - # Handle type constructor calls like t.CDouble(1e-9), t.CFloat(3.14), t.CInt(42) + # Handle type constructor calls like CDouble(1e-9), CFloat(3.14), CInt(42) if isinstance(value_node, ast.Call): inner_val: ir.Constant | None = self._eval_type_ctor_const(value_node, var_type, Gen) if inner_val is not None: @@ -2298,12 +2292,11 @@ class AssignHandle(BaseHandle): return None def _eval_type_ctor_const(self, call_node: ast.Call, var_type: ir.Type, Gen: "Translator.LlvmGen") -> ir.Constant | None: - """Try to evaluate t.CDouble(val), t.CFloat(val), t.CInt(val) etc. as a compile-time constant.""" - if not isinstance(call_node.func, ast.Attribute): + """Try to evaluate CDouble(val), CFloat(val), CInt(val) etc. as a compile-time constant.""" + if not isinstance(call_node.func, ast.Name): return None - if not isinstance(call_node.func.value, ast.Name): - return None - if call_node.func.value.id != 't': + ctor_cls: type | None = getattr(TypeSystem, call_node.func.id, None) + if not isinstance(ctor_cls, type) or not issubclass(ctor_cls, TypeSystem.CType): return None if not call_node.args or len(call_node.args) != 1: return None diff --git a/lib/core/Handles/HandlesAsyncFunctions.py b/lib/core/Handles/HandlesAsyncFunctions.py index 7b32ba4..c6c5159 100644 --- a/lib/core/Handles/HandlesAsyncFunctions.py +++ b/lib/core/Handles/HandlesAsyncFunctions.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: import vast as ast import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, EXCEPTION_CODE_MAP -from lib.includes import t +from lib.core import TypeSystem class AsyncFunctionHandle(BaseHandle): @@ -634,7 +634,7 @@ class AsyncFunctionHandle(BaseHandle): TypeInfo: CTypeInfo | None = self.Trans.TypeMergeHandler.GetCTypeInfo(stmt.annotation) if TypeInfo is None: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CInt() + TypeInfo.BaseType = TypeSystem.CInt() if self.Trans.VarScopes: self.Trans.VarScopes[-1][target] = TypeInfo Gen._record_var_signedness(target, False) diff --git a/lib/core/Handles/HandlesAugAssign.py b/lib/core/Handles/HandlesAugAssign.py index d4f9637..faa4e07 100644 --- a/lib/core/Handles/HandlesAugAssign.py +++ b/lib/core/Handles/HandlesAugAssign.py @@ -27,11 +27,11 @@ class AugAssignHandle(BaseHandle): """解析 global 变量的 LLVM 类型:优先用模块级 AnnAssign 的注解类型。 问题场景:函数内 `_g_alloc_count += 1`(global 声明),模块级注解为 - `_g_alloc_count: t.CSizeT`(i64)。若不查模块级注解类型,此处会用 RHS 字面量 + `_g_alloc_count: CSizeT`(i64)。若不查模块级注解类型,此处会用 RHS 字面量 类型(i32)自动建 i32 全局,与模块内其他读取/写入(i64)类型不匹配, 产生 "Operands must be the same type, got (i64, i32)" 类错误。 模块级 AnnAssign 已通过 _EmitGlobalAnnAssignLlvm 创建 LLVM 全局, - 但注解无初始值(如 `_g_alloc_max: t.CSizeT = 0`)时 initializer 为空、 + 但注解无初始值(如 `_g_alloc_max: CSizeT = 0`)时 initializer 为空、 Gen.module.globals 中无该符号,故需在此兜底解析注解类型。 """ module_ann: dict = getattr(Gen, '_module_ann_types', None) diff --git a/lib/core/Handles/HandlesBase.py b/lib/core/Handles/HandlesBase.py index cb7f754..b23f3fe 100644 --- a/lib/core/Handles/HandlesBase.py +++ b/lib/core/Handles/HandlesBase.py @@ -10,8 +10,8 @@ from enum import IntFlag, auto from llvmlite import ir as _ir from lib.constants import config as _config -from lib.includes import t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry from lib.core.TypeSpec import TypeSpec, SymbolMeta, FIELD_ROUTES from lib.core.SymbolUtils import ( IsPtrSubscriptNode, IsListAnnotation, IsCPtrMarkerNode, @@ -66,20 +66,20 @@ class CTypeInfo: C 类型信息对象 - 统一符号表条目和类型计算 设计原则: - - BaseType 是 CType 实例(来自 t 模块),永远不使用硬编码字符串 + - BaseType 是 CType 实例(内建类型),永远不使用硬编码字符串 - 描述符分为两种: - VarConst/VarVolatile: 变量本身(指针)的限定符,如 int * const - DataConst/DataVolatile: 指向数据的限定符,如 const int * 属性(类型计算): - - BaseType: t.CType - 基础类型实例 (如 t.CInt(), t.CVoid()) + - BaseType: CType - 基础类型实例 (如 CInt(), CVoid()) - PtrCount: int - 指针层数 - VarConst: bool - 变量本身(指针)是否 const,如 int * const - VarVolatile: bool - 变量本身(指针)是否 volatile - DataConst: bool - 指向的数据是否 const,如 const int * - DataVolatile: bool - 指向的数据是否 volatile - ArrayDims: List[str] - 数组维度 - - Storage: t.CType - 存储类 (static, extern 等) + - Storage: CType - 存储类 (static, extern 等) - IsFuncPtr: bool - 是否函数指针 - FuncPtrParams: List[Tuple[str, CTypeInfo]] - 函数指针参数列表,每个元素是 (参数名, 参数类型) - FuncPtrReturn: CTypeInfo - 函数指针返回类型 @@ -127,17 +127,17 @@ class CTypeInfo: @property - def BaseType(self) -> t.CType | tuple | None: + def BaseType(self) -> TypeSystem.CType | tuple | None: return self._ts._base_type @BaseType.setter - def BaseType(self, value: t.CType | type | tuple | List | None) -> None: + def BaseType(self, value: TypeSystem.CType | type | tuple | List | None) -> None: """设置 BaseType,接受以下类型: - None: 清空 - - t.CType 实例: 单个类型,自动设置 IsStruct/IsEnum/IsUnion 标志 - - type (CType 子类): 如 t.CStruct,自动实例化 - - tuple/list of t.CType: 多个组合类型 + - CType 实例: 单个类型,自动设置 IsStruct/IsEnum/IsUnion 标志 + - type (CType 子类): 如 CStruct,自动实例化 + - tuple/list of CType: 多个组合类型 """ ts: TypeSpec = self._ts sm: SymbolMeta = self._sm @@ -153,62 +153,62 @@ class CTypeInfo: if isinstance(value, (tuple, list)): ts._base_type = tuple(value) for v in value: - if isinstance(v, t.CStruct): + if isinstance(v, TypeSystem.CStruct): sm.is_struct = True - elif isinstance(v, t.CEnum): + elif isinstance(v, TypeSystem.CEnum): sm.is_enum = True - elif isinstance(v, t.CUnion): + elif isinstance(v, TypeSystem.CUnion): sm.is_union = True - elif isinstance(v, t.REnum): + elif isinstance(v, TypeSystem.REnum): sm.is_renum = True sm.is_enum = True return - if isinstance(value, type) and issubclass(value, t.CType): + if isinstance(value, type) and issubclass(value, TypeSystem.CType): ts._base_type = value() return - if isinstance(value, t.CType): + if isinstance(value, TypeSystem.CType): ts._base_type = value - if isinstance(value, t.CStruct): + if isinstance(value, TypeSystem.CStruct): sm.is_struct = True sm.is_enum = False sm.is_union = False sm.is_renum = False - elif isinstance(value, t.REnum): + elif isinstance(value, TypeSystem.REnum): sm.is_renum = True sm.is_enum = True sm.is_struct = False sm.is_union = False - elif isinstance(value, t.CEnum): + elif isinstance(value, TypeSystem.CEnum): sm.is_enum = True sm.is_struct = False sm.is_union = False sm.is_renum = False - elif isinstance(value, t.CUnion): + elif isinstance(value, TypeSystem.CUnion): sm.is_union = True sm.is_struct = False sm.is_enum = False sm.is_renum = False return - raise TypeError(f"BaseType must be t.CType instance, type subclass, or tuple of t.CType, got {type(value)}") + raise TypeError(f"BaseType must be CType instance, type subclass, or tuple of CType, got {type(value)}") @property def TypeCls(self) -> type | None: """获取 CType 类(从 BaseType 推断)""" - bt: t.CType | tuple | None = self._ts._base_type + bt: TypeSystem.CType | tuple | None = self._ts._base_type if bt: return type(bt) sm: SymbolMeta = self._sm if sm.is_struct: - return t.CStruct + return TypeSystem.CStruct if sm.is_enum: - return t.CEnum + return TypeSystem.CEnum if sm.is_union: - return t.CUnion + return TypeSystem.CUnion if sm.is_typedef: - return t._CTypedef + return TypeSystem._CTypedef return None @property @@ -217,37 +217,37 @@ class CTypeInfo: @property def IsVoid(self) -> bool: - return isinstance(self._ts._base_type, t.CVoid) + return isinstance(self._ts._base_type, TypeSystem.CVoid) @property def IsStr(self) -> bool: - return isinstance(self._ts._base_type, t.CChar) and self._ts.ptr_count > 0 + return isinstance(self._ts._base_type, TypeSystem.CChar) and self._ts.ptr_count > 0 @property def IsInt(self) -> bool: - bt: t.CType | tuple | None = self._ts._base_type - return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is not None and bt.IsSigned is True and not isinstance(bt, t.CVoid) + bt: TypeSystem.CType | tuple | None = self._ts._base_type + return isinstance(bt, TypeSystem.CType) and getattr(bt, 'IsSigned', None) is not None and bt.IsSigned is True and not isinstance(bt, TypeSystem.CVoid) @property def IsUInt(self) -> bool: - bt: t.CType | tuple | None = self._ts._base_type - return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is False + bt: TypeSystem.CType | tuple | None = self._ts._base_type + return isinstance(bt, TypeSystem.CType) and getattr(bt, 'IsSigned', None) is False @property def IsFloat(self) -> bool: - bt: t.CType | tuple | None = self._ts._base_type - return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is None and getattr(bt, 'Size', 0) in (32, 64, 128) and not isinstance(bt, t.CVoid) + bt: TypeSystem.CType | tuple | None = self._ts._base_type + return isinstance(bt, TypeSystem.CType) and getattr(bt, 'IsSigned', None) is None and getattr(bt, 'Size', 0) in (32, 64, 128) and not isinstance(bt, TypeSystem.CVoid) def ToString(self) -> str: ts: TypeSpec = self._ts sm: SymbolMeta = self._sm - bt: t.CType | tuple | None = ts._base_type + bt: TypeSystem.CType | tuple | None = ts._base_type if ts.is_func_ptr: return 'Callable' parts: list[str] = [] - if ts.storage and not isinstance(ts.storage, t.CExport): + if ts.storage and not isinstance(ts.storage, TypeSystem.CExport): parts.append(type(ts.storage).__name__) if ts.data_const or ts.data_volatile: @@ -265,9 +265,9 @@ class CTypeInfo: elif bt: if isinstance(bt, str): base_name = bt - elif isinstance(bt, type) and issubclass(bt, t.CType): + elif isinstance(bt, type) and issubclass(bt, TypeSystem.CType): base_name = bt.__name__ - elif isinstance(bt, t.CType): + elif isinstance(bt, TypeSystem.CType): # 对命名的 CType(CStruct/CEnum/CUnion/REnum),优先使用其 name 属性 # 否则回退到类名(如 'CInt'、'CChar') _named: str | None = getattr(bt, 'name', None) @@ -320,13 +320,13 @@ class CTypeInfo: """从类型名字符串创建 CTypeInfo(兼容旧 API)""" info: CTypeInfo = CTypeInfo() if TypeName.startswith('struct '): - info.BaseType = t.CStruct(name=TypeName[7:].strip()) if TypeName[7:].strip() else t.CStruct() + info.BaseType = TypeSystem.CStruct(name=TypeName[7:].strip()) if TypeName[7:].strip() else TypeSystem.CStruct() elif TypeName.startswith('enum '): - info.BaseType = t.CEnum(name=TypeName[5:].strip()) if TypeName[5:].strip() else t.CEnum() + info.BaseType = TypeSystem.CEnum(name=TypeName[5:].strip()) if TypeName[5:].strip() else TypeSystem.CEnum() elif TypeName.startswith('union '): - info.BaseType = t.CUnion(name=TypeName[6:].strip()) if TypeName[6:].strip() else t.CUnion() + info.BaseType = TypeSystem.CUnion(name=TypeName[6:].strip()) if TypeName[6:].strip() else TypeSystem.CUnion() else: - info.BaseType = t.CStruct(name=TypeName) + info.BaseType = TypeSystem.CStruct(name=TypeName) return info # LLVM primitive type name → (CTypeClass, PtrCount) mapping @@ -338,16 +338,16 @@ class CTypeInfo: if cls._LLVM_PRIMITIVE_MAP is not None: return cls._LLVM_PRIMITIVE_MAP cls._LLVM_PRIMITIVE_MAP = { - 'void': (t.CVoid, 0), - 'i1': (t.CInt, 0), - 'i8': (t.CChar, 0), - 'i16': (t.CShort, 0), - 'i32': (t.CInt, 0), - 'i64': (t.CLong, 0), - 'i128': (t.CInt, 0), - 'float': (t.CFloat, 0), - 'double': (t.CDouble, 0), - 'fp128': (t.CFloat128T, 0), + 'void': (TypeSystem.CVoid, 0), + 'i1': (TypeSystem.CInt, 0), + 'i8': (TypeSystem.CChar, 0), + 'i16': (TypeSystem.CShort, 0), + 'i32': (TypeSystem.CInt, 0), + 'i64': (TypeSystem.CLong, 0), + 'i128': (TypeSystem.CInt, 0), + 'float': (TypeSystem.CFloat, 0), + 'double': (TypeSystem.CDouble, 0), + 'fp128': (TypeSystem.CFloat128T, 0), } return cls._LLVM_PRIMITIVE_MAP @@ -401,7 +401,7 @@ class CTypeInfo: @staticmethod def VoidTypeInfo() -> "CTypeInfo": info: CTypeInfo = CTypeInfo() - info.BaseType = t.CVoid() + info.BaseType = TypeSystem.CVoid() return info def ToLLVM(self, Gen: LlvmCodeGenerator) -> _ir.Type: @@ -429,14 +429,17 @@ class CTypeHelper: @staticmethod def GetTModuleCType(TypeName: str) -> type | None: + alias: type | None = TypeSystem.BUILTIN_TYPE_ALIASES.get(TypeName) + if alias is not None: + return alias result: type | None = CTypeRegistry.GetClassByName(TypeName) if result is not None: return result - TypeClass: type | None = getattr(t, TypeName, None) - if TypeClass and isinstance(TypeClass, type) and issubclass(TypeClass, t.CType): + TypeClass: type | None = getattr(TypeSystem, TypeName, None) + if TypeClass and isinstance(TypeClass, type) and issubclass(TypeClass, TypeSystem.CType): return TypeClass - FallbackClass: type | None = getattr(t, f'_{TypeName}', None) - if FallbackClass and isinstance(FallbackClass, type) and issubclass(FallbackClass, t.CType): + FallbackClass: type | None = getattr(TypeSystem, f'_{TypeName}', None) + if FallbackClass and isinstance(FallbackClass, type) and issubclass(FallbackClass, TypeSystem.CType): return FallbackClass return None @@ -449,7 +452,7 @@ class CTypeHelper: if cls: return cls.__name__ return type_or_name - elif isinstance(type_or_name, type) and issubclass(type_or_name, t.CType): + elif isinstance(type_or_name, type) and issubclass(type_or_name, TypeSystem.CType): return type_or_name.__name__ return '' @@ -458,8 +461,8 @@ class BuiltinTypeMap: """ 内置类型映射表 - 字符串到 (CType类, PtrCount) 的映射 - 用法:BuiltinTypeMap.Get('int') -> (t.CInt, 0) - BuiltinTypeMap.Get('BYTEPTR') -> (t.CUnsignedChar, 1) + 用法:BuiltinTypeMap.Get('int') -> (CInt, 0) + BuiltinTypeMap.Get('BYTEPTR') -> (CUnsignedChar, 1) """ _map: dict[str, tuple[type, int]] | None = None @@ -475,7 +478,7 @@ class BuiltinTypeMap: # C 头文件 stub 生成器使用独立的硬编码表(CTypeMapper._CNAME_TO_PY)。 for pyname, ctype_cls in CTypeRegistry._name_to_class.items(): pos: frozenset = getattr(ctype_cls, 'position', frozenset()) - if t.CType.POINTER in pos and t.CType.BASE not in pos: + if TypeSystem.CType.POINTER in pos and TypeSystem.CType.BASE not in pos: cls._map[pyname] = (ctype_cls, 1) else: cls._map[pyname] = (ctype_cls, 0) @@ -483,28 +486,33 @@ class BuiltinTypeMap: # 包含 Python 内置类型名(int/float/bool)和 C 类型名速记(char/short/long 等)。 _SPECIAL: dict[str, tuple[type, int]] = { # Python 内置类型名 - 'str': (t.CChar, 1), 'bytes': (t.CChar, 1), - 'int': (t.CInt, 0), 'float': (t.CFloat, 0), 'bool': (t.CBool, 0), + 'str': (TypeSystem.CChar, 1), 'bytes': (TypeSystem.CChar, 1), + 'int': (TypeSystem.CInt, 0), 'float': (TypeSystem.CFloat, 0), 'bool': (TypeSystem.CBool, 0), # C 类型名速记 - 'char': (t.CChar, 0), 'short': (t.CShort, 0), - 'long': (t.CLong, 0), 'long long': (t.CLongLong, 0), - 'double': (t.CDouble, 0), - 'unsigned': (t.CUnsigned, 0), - 'signed': (t.CInt, 0), 'signed int': (t.CInt, 0), - 'signed char': (t.CSignedChar, 0), - 'void': (t.CVoid, 0), 'Void': (t.CVoid, 0), + 'char': (TypeSystem.CChar, 0), 'short': (TypeSystem.CShort, 0), + 'long': (TypeSystem.CLong, 0), 'long long': (TypeSystem.CLongLong, 0), + 'double': (TypeSystem.CDouble, 0), + 'unsigned': (TypeSystem.CUnsigned, 0), + 'signed': (TypeSystem.CInt, 0), 'signed int': (TypeSystem.CInt, 0), + 'signed char': (TypeSystem.CSignedChar, 0), + 'void': (TypeSystem.CVoid, 0), 'Void': (TypeSystem.CVoid, 0), } for k, v in _SPECIAL.items(): if k not in cls._map: cls._map[k] = v _FLOAT_ALIASES: dict[str, tuple[type, int]] = { - 'FLOAT8': (t.CFloat8T, 0), 'FLOAT16': (t.CFloat16T, 0), - 'FLOAT32': (t.CFloat32T, 0), 'FLOAT64': (t.CFloat64T, 0), - 'FLOAT128': (t.CFloat128T, 0), + 'FLOAT8': (TypeSystem.CFloat8T, 0), 'FLOAT16': (TypeSystem.CFloat16T, 0), + 'FLOAT32': (TypeSystem.CFloat32T, 0), 'FLOAT64': (TypeSystem.CFloat64T, 0), + 'FLOAT128': (TypeSystem.CFloat128T, 0), } for k, v in _FLOAT_ALIASES.items(): if k not in cls._map: cls._map[k] = v + # 内建短名(int8/sizet/uchar/...):源码直接书写,不依赖任何 typedef。 + for _alias_name, _alias_cls in TypeSystem.BUILTIN_TYPE_ALIASES.items(): + _pos: frozenset = getattr(_alias_cls, 'position', frozenset()) + _ptr: int = 1 if TypeSystem.CType.POINTER in _pos and TypeSystem.CType.BASE not in _pos else 0 + cls._map[_alias_name] = (_alias_cls, _ptr) return cls._map @classmethod @@ -882,16 +890,16 @@ class BaseHandle: return member_ptr return None - def _IsTModuleType(self, TypeName: str) -> bool: - if TypeName in ('t', 'State', 'Bit', 'Anonymous', 'Postdefinition'): + def _IsBuiltinTypeName(self, TypeName: str) -> bool: + if TypeName in ('State', 'Bit', 'Anonymous', 'Postdefinition'): return True - TypeClass: type | None = getattr(t, TypeName, None) + TypeClass: type | None = getattr(TypeSystem, TypeName, None) if TypeClass and isinstance(TypeClass, type): - if issubclass(TypeClass, t.CType): + if issubclass(TypeClass, TypeSystem.CType): return True - FallbackClass: type | None = getattr(t, f'_{TypeName}', None) + FallbackClass: type | None = getattr(TypeSystem, f'_{TypeName}', None) if FallbackClass and isinstance(FallbackClass, type): - if issubclass(FallbackClass, t.CType): + if issubclass(FallbackClass, TypeSystem.CType): return True return False @@ -936,7 +944,7 @@ class BaseHandle: # 回退到 CInt if elem_type_info is None and fallback_to_cint: elem_type_info = CTypeInfo() - elem_type_info.BaseType = t.CInt() + elem_type_info.BaseType = TypeSystem.CInt() elem_type: Any = Gen._ctype_to_llvm(elem_type_info) if isinstance(elem_type, _ir.VoidType): @@ -1019,11 +1027,11 @@ class BaseHandle: """解析注解类型,BinOp(BitOr) 优先使用 MergeTypes,其他使用 FromNode。 统一处理函数返回类型和参数类型的 BinOp 联合类型解析。 - 指针下标(rawptr[T] 内置裸指针 / t.CPtr[T] / 裸名 CPtr[T],三者等价 - `T | t.CPtr`)同样交给 TypeMerge 解析:内层 T 走通用类型解析(含跨模块 - 类经 Gen.structs 反查 SHA1 前缀),指针层数与源码 `T | t.CPtr` 一致; + 指针下标(rawptr[T] 内置裸指针 / CPtr[T] / 裸名 CPtr[T],三者等价 + `T | CPtr`)同样交给 TypeMerge 解析:内层 T 走通用类型解析(含跨模块 + 类经 Gen.structs 反查 SHA1 前缀),指针层数与源码 `T | CPtr` 一致; 若交给 CTypeInfo.FromNode(TypeAnnotationResolver)解析, - rawptr[ast.AST] 会退化成 CVoid/1(i8*)、t.CPtr[ast.AST] 亦退化成 + rawptr[ast.AST] 会退化成 CVoid/1(i8*)、CPtr[ast.AST] 亦退化成 CVoid/1(其 Subscript-CPtr 分支不带 Gen.structs 反查),与 declare 端 %".AST"* 分裂。 命中泛型模板的泛型容器下标(list[X] / rawptr[list[X]] 等)同样交 @@ -1059,7 +1067,7 @@ class BaseHandle: def _ResolveStackArrayElementFallback( self, annotation: ast.expr, Fallback: CTypeInfo | None) -> CTypeInfo | None: - """固定数组注解(`t.CArray[T, N]` / `[N]T`)元素类型兜底解析。 + """固定数组注解(`CArray[T, N]` / `[N]T`)元素类型兜底解析。 CTypeInfo.FromNode(TypeAnnotationResolver 的 IsListAnnotation 分支)只 会用自身解析元素类型:元素命中泛型模板时(list[X] / list[rawptr[X]])解 @@ -1071,7 +1079,7 @@ class BaseHandle: (ResolveAnnotationType 递归,泛型容器因此走 TypeMerge 特化,跨模块类 经 Gen.structs 反查 SHA1)解析元素,再套上数组维度(维度序与 TypeAnnotationResolver 的 `insert(0, count)` 一致)。 - 元素可解析的形态(t.CArray[t.CInt, 8] / t.CArray[Node, 4] / 嵌套 CArray) + 元素可解析的形态(CArray[CInt, 8] / CArray[Node, 4] / 嵌套 CArray) 保持 FromNode 结果原样,避免改动既有布局。 """ if isinstance(Fallback, CTypeInfo) and Fallback.BaseType is not None: @@ -1092,7 +1100,7 @@ class BaseHandle: return Result def _ResolveAttributeAnnotationType(self, annotation: ast.Attribute) -> CTypeInfo | None: - """Attribute 注解(`t.CInt` / `ast.AST` / `.CLS`)解析。 + """Attribute 注解(`CInt` / `ast.AST` / `.CLS`)解析。 先走 CTypeInfo.FromNode(TypeAnnotationResolver,覆盖 t/c 内建与已在本模块 SymbolTable 注册的类):其 BaseType 已解析时语义不变。 @@ -1103,7 +1111,7 @@ class BaseHandle: SymbolUtils._ResolveAttributeArgStr 同一条"类名 → SHA1"规则)。 不修此路时跨模块类 Attribute(`rawptr[.CLS]` 脱糖后的 - `.CLS | t.CPtr`、泛型 T 替换出的裸 `.CLS`、`list[ast.AST]` + `.CLS | CPtr`、泛型 T 替换出的裸 `.CLS`、`list[ast.AST]` 特化的 `append(item: T)`)在定义端判为"无法识别的参数类型注解"抛 SyntaxError,被上层 broad except 吞掉后退化为 i32/i8*,而声明端给 `%".CLS"*`,字段/签名两侧不一致。 @@ -1143,7 +1151,7 @@ class BaseHandle: info: CTypeInfo | None = merger.MergeTypes(annotation) if info is not None and isinstance(info, CTypeInfo): return info - # 指针下标参数注解(rawptr[T] / t.CPtr[T] / 裸名 CPtr[T],含 + # 指针下标参数注解(rawptr[T] / CPtr[T] / 裸名 CPtr[T],含 # rawptr[list[X]] 等容器:_SubscriptHitsGenericTemplate 也命中,但统一交 # ResolveAnnotationType 处理更简单——它已把指针下标路由到 TypeMerge)。 if IsPtrSubscriptNode(annotation, self.Trans.SymbolTable): @@ -1171,7 +1179,7 @@ class BaseHandle: def _SubscriptHitsGenericTemplate(self, annotation: ast.Subscript) -> bool: """判断 Subscript 是否命中泛型模板:裸模板名(list[X]/GSList[X]), - 或 rawptr/t.CPtr 裸指针 typedef 内嵌模板名(rawptr[list[X]] 等)。""" + 或 rawptr/CPtr 裸指针 typedef 内嵌模板名(rawptr[list[X]] 等)。""" tpls: Any = getattr(getattr(self.Trans, 'ClassHandler', None), '_generic_class_templates', None) if not tpls: return False @@ -1239,7 +1247,7 @@ class BaseHandle: **不再静默兜底**(原实现:注解解析返回 None → i32;_ctype_to_llvm 得 void → i8*; 任何异常 → i32 + TypeInfo=None)。这些兜底会把"注解没解析出来"伪装成一个 具体类型,下游于是报出与真因无关的错——实测:`free_lists: uint64*`(脱糖为 - `uint64 | t.CPtr`)在解析异常时被当成 **i32**,`self.free_lists = base`(i8*) + `uint64 | CPtr`)在解析异常时被当成 **i32**,`self.free_lists = base`(i8*) 便误报"指针隐式转整数已禁止"。类型信息缺失一律响亮失败。 非 AnnAssign/Name 目标时返回 None。 """ @@ -1283,7 +1291,7 @@ class BaseHandle: f"Name={getattr(TypeInfo, 'Name', None)})—— 拒绝静默退化为 i8*" ) # 「内层是类引用却解析成通用指针」fail-fast(降级源头定位): - # `rawptr[Mod.Class]` / `Mod.Class | t.CPtr` 的语义是"指向该类",内层若确实是 + # `rawptr[Mod.Class]` / `Mod.Class | CPtr` 的语义是"指向该类",内层若确实是 # 已定义类,解析结果必须带该类 BaseType;退化成 void 基座(i8* / 多一层 i8**) # 就是类型信息被丢掉 —— 该值一旦进 class_members 就会被冻进 struct body # (llvmlite set_body 只能设一次),后期只修表不修体(现场:Generator 第 3/11 @@ -1337,16 +1345,16 @@ class BaseHandle: 只拦"必属类型信息丢失"的组合:内层节点(Name / Attribute)的名字在 `Gen.structs`(本模块已建)或 `Gen._struct_sha1_map`(预扫描的类→模块映射) - 中有类定义,而解析出的 `BaseType` 是 `t.CVoid` **且没有任何类身份** + 中有类定义,而解析出的 `BaseType` 是 `CVoid` **且没有任何类身份** (IsStruct / IsRenum / IsEnum / Name 全空)。其余一律放行 (`rawptr[rawptr]` 这类本就 void 基座的多层指针、模块名、泛型特化实参等)。 """ if Info is None or Info.BaseType is None: return - if not (Info.BaseType is t.CVoid or isinstance(Info.BaseType, t.CVoid)): + if not (Info.BaseType is TypeSystem.CVoid or isinstance(Info.BaseType, TypeSystem.CVoid)): return # 只要还带着任何"类身份"(IsStruct / IsRenum / IsEnum / Name),就不是信息丢失: - # REnum 类型条目本身 BaseType=None,`T | t.CPtr` 合并后会被默认填成 CVoid,但 + # REnum 类型条目本身 BaseType=None,`T | CPtr` 合并后会被默认填成 CVoid,但 # IsRenum/IsStruct/Name 齐备,_ctype_to_llvm 仍能解析出 %.T* —— 误判会 # 把合法注解(如 REnum 变体载荷 `Pointee: rawptr[LLVMType]`)打成致命错误。 if (getattr(Info, 'IsStruct', False) or getattr(Info, 'IsRenum', False) diff --git a/lib/core/Handles/HandlesBody.py b/lib/core/Handles/HandlesBody.py index b9f2fcb..a5237f4 100644 --- a/lib/core/Handles/HandlesBody.py +++ b/lib/core/Handles/HandlesBody.py @@ -19,7 +19,7 @@ class BodyHandle(BaseHandle): Gen._set_node_info(Node) try: if isinstance(Node, ast.Expr): - # `fallthrough`(vast 关键字已脱糖为 c.NoBreak())是 switch 的 + # `fallthrough`(vast 关键字已脱糖为 NoBreak())是 switch 的 # 标记语句,本身不产出 IR,语义由 HandlesMatch 消费(case 体因此 # 不自动跳出 switch);合法位置**只有 switch 的 case 体内**, # match(完全禁止 fallthrough)或 switch 之外一律 fail-fast。 @@ -99,15 +99,14 @@ class BodyHandle(BaseHandle): if Gen.builder and not Gen.builder.block.is_terminated: Gen._EmitTempFrees() - @staticmethod - def _IsNoBreakMarkerStmt(Node: ast.stmt) -> bool: - """是否 `c.NoBreak()` 标记语句(`fallthrough` 软关键字的脱糖形态)""" - if not isinstance(Node, ast.Expr) or not isinstance(Node.value, ast.Call): - return False - Fn: ast.expr = Node.value.func - return (isinstance(Fn, ast.Attribute) and isinstance(Fn.value, ast.Name) - and Fn.value.id == 'c' and Fn.attr == 'NoBreak') - + @staticmethod + def _IsNoBreakMarkerStmt(Node: ast.stmt) -> bool: + """是否 `NoBreak()` 标记语句(`fallthrough` 软关键字的脱糖形态)""" + if not isinstance(Node, ast.Expr) or not isinstance(Node.value, ast.Call): + return False + Fn: ast.expr = Node.value.func + return isinstance(Fn, ast.Name) and Fn.id == 'NoBreak' + def HandleExprLlvm(self, Node: ast.expr, VarType: ir.Type | None = None, ConstWidthHint: int | None = None) -> ir.Value | None: return self.Trans.ExprHandler.HandleExprLlvm(Node, VarType, ConstWidthHint) \ No newline at end of file diff --git a/lib/core/Handles/HandlesClassDef.py b/lib/core/Handles/HandlesClassDef.py index b01a06e..0f3328a 100644 --- a/lib/core/Handles/HandlesClassDef.py +++ b/lib/core/Handles/HandlesClassDef.py @@ -10,17 +10,17 @@ import llvmlite.ir as ir from lib.core.Exportable import EnumMember as ExportEnumMember from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta from lib.core.SymbolUtils import ( - IsTModule, FindStructNameInAnnotationWithContext, MangleTypeArgByRegistry, + FindStructNameInAnnotationWithContext, MangleTypeArgByRegistry, EnumClassIntWidth, EnumBodyMemberNames, EnumMemberCountMismatchError, ClassHasFuncLevelCVTable, IsVtableSlotMethod) from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode -from lib.includes import t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry -# 枚举成员不允许的指针形态名:t.CPtr 家族(CPtr/CAutoPtr,后者继承 -# CPtr)、值引用标记(CRef/CTempRef,`&T`/`&temp T`)、内建 rawptr(= t.CPtr)、 +# 枚举成员不允许的指针形态名:CPtr 家族(CPtr/CAutoPtr,后者继承 +# CPtr)、值引用标记(CRef/CTempRef,`&T`/`&temp T`)、内建 rawptr(= CPtr)、 # str/bytes(= i8*)。枚举值是整数常量,指针成员语义不成立,命中即明确报错 # (不静默当 int)。 _ENUM_PTR_ANNOTATION_NAMES: frozenset[str] = frozenset({ @@ -115,8 +115,8 @@ class ClassHandle(BaseHandle): - ast.Name:'AST'(未注册类)或 'sha1.AST'(旧式点号名)→ 去前缀; - ast.Attribute:'sha1.AST' 经 _make_replacement_node/_make_name_node 产出的 Attribute 链(Name('sha1').AST)→ attr 名。 - 其余(Union `X | t.CPtr`、Subscript `list[T]`、内建)→ None,不追加 - 指针层(已显式写了 `| t.CPtr` 的注解不再重复加层)。 + 其余(Union `X | CPtr`、Subscript `list[T]`、内建)→ None,不追加 + 指针层(已显式写了 `| CPtr` 的注解不再重复加层)。 """ if isinstance(Node, ast.Name): Name: str = Node.id @@ -177,24 +177,24 @@ class ClassHandle(BaseHandle): # 都不在类表里 → 天然判为值类型,无需名表。 # 历史教训(名表判据的代价,保留以便回归时理解):`str` 曾漏在 # "非类类型名"集合外 → `list[str]` 的类型参数被误判为类类型,特化后 - # 方法签名被额外包一层 `| t.CPtr`(append/set 形参 i8**、get/pop 返回 + # 方法签名被额外包一层 `| CPtr`(append/set 形参 i8**、get/pop 返回 # i8**)→ 调用点多解一层 load(读字符串首 8 字节)→ ASan 崩溃。 # 注意 _BUILTIN_TYPE_NAMES 本身仍保留:它用于 type_map 替换 - # 与 _t_c_imported_names 注册,不能把 'str' 并进去 - # (否则 HandlesTypeMerge 会把注解 `str` 当 `t.str` 解析)。 + # 与 _from_import_aliases 注册,不能把 'str' 并进去 + # (否则 HandlesTypeMerge 会把注解 `str` 当内建类型名参与替换)。 type_map: dict[str, str] = {} for i, tp_name in enumerate(type_param_names): if type_names and i < len(type_names): tn: str = type_names[i] - # 判断是否为 t 模块内建类型(裸名或 't.' 前缀,如 'CInt'/'t.CInt'): - # 内建类型必须用源码名(type_name)替换 T(t.CInt → i32),否则 + # 判断是否为内建类型名(如 'CInt'): + # 内建类型必须用源码名(type_name)替换 T(CInt → i32),否则 # 用 mangled type_arg(如 'i32')替换会产生 'i32.__sizeof__' 这类 # 源码中不存在的名称([FATAL][__sizeof__] 类型 'i32' 无法解析)。 # 真正的类类型参数(如 'AST'/'ast.AST')才用 mangled type_arg # (带 sha1 前缀 + ptr 后缀),避免模板内部嵌套注解被替换成裸短名 # 后重新特化出只有 declare、无方法体的错误特化(list[AST].__len__ # undefined symbol 根因)。_make_replacement_node 会把 mangled 名 - # 还原为 'sha1.AST | t.CPtr',重新解析时拼回一致的 mangled 名。 + # 还原为 'sha1.AST | CPtr',重新解析时拼回一致的 mangled 名。 tn_bare: str = tn.split('.')[-1] if '.' in tn else tn if tn_bare in _BUILTIN_TYPE_NAMES: type_map[tp_name] = tn @@ -204,11 +204,11 @@ class ClassHandle(BaseHandle): type_map[tp_name] = tn else: type_map[tp_name] = type_args[i] - # 检测哪些类型参数在原始类型实参中带有指针语义(| t.CPtr / rawptr[T]) + # 检测哪些类型参数在原始类型实参中带有指针语义(| CPtr / rawptr[T]) # 当 type_arg 以 '*' 结尾(mangling 把每个 CPtr 层渲染为一层 '*')且对应的 # type_name(去模块前缀后)不是内建类型名时,说明调用方写了 - # list[AST | t.CPtr] / list[rawptr[AST]]。注意用 tn_bare 判断: - # 't.CPtr' 去前缀后是 'CPtr'(内建),不算类类型参数。 + # list[AST | CPtr] / list[rawptr[AST]]。注意用 tn_bare 判断: + # 'CPtr' 去前缀后是 'CPtr'(内建),不算类类型参数。 cptr_params: set[str] = set() for i, tp_name in enumerate(type_param_names): type_arg: str = type_args[i] @@ -218,8 +218,8 @@ class ClassHandle(BaseHandle): if tn_bare_c not in _BUILTIN_TYPE_NAMES: cptr_params.add(tp_name) # Bug 2 修复:识别特化为 class 类型的类型参数 - # 这类参数在方法签名中是裸 T(无 | t.CPtr),特化后为裸 ClassName(值类型) - # 需要加 | t.CPtr 使其成为指针类型(class 实例应按指针传递) + # 这类参数在方法签名中是裸 T(无 | CPtr),特化后为裸 ClassName(值类型) + # 需要加 | CPtr 使其成为指针类型(class 实例应按指针传递) # 判据 = "是否有类定义"(_HasClassDefinition),存**裸名**:注解侧的 # 比较也用裸名(T 替换后的 'sha1.Param' 去前缀)——此前存带模块前缀的 # tn(如 'ast.AST')而比较用裸名 'AST',前缀形态永不命中。 @@ -229,142 +229,40 @@ class ClassHandle(BaseHandle): tn_bare_cls: str = tn.split('.')[-1] if '.' in tn else tn if self._HasClassDefinition(tn_bare_cls, Gen): class_type_names.add(tn_bare_cls) - # 仅对 t 模块内建类型名注册 _t_c_imported_names(如 CInt -> ('t','CInt')) - # 类名(如 AST)不应注册为 t.AST,否则会污染名称解析 - if type_names: - if not hasattr(self.Trans, '_t_c_imported_names'): - self.Trans._t_c_imported_names = {} - for tn in type_names: - if tn in _BUILTIN_TYPE_NAMES and tn not in self.Trans._t_c_imported_names: - self.Trans._t_c_imported_names[tn] = ('t', tn) - SpecNode: ast.ClassDef = copy.deepcopy(Node) - SpecNode.type_params = [] - SpecNode.name = spec_name - for item in SpecNode.body: - if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name): - if item.annotation: - item.annotation = self.Trans.FunctionHandler._replace_type_in_annotation(item.annotation, type_map, cptr_params) - elif isinstance(item, ast.FunctionDef): - for arg in item.args.args: - if arg.annotation: - arg.annotation = self.Trans.FunctionHandler._replace_type_in_annotation(arg.annotation, type_map, cptr_params) - # class 类型参数加指针语义:T -> GNode -> GNode | t.CPtr - # T 替换后的真实形态是 Attribute 链('.GNode' → - # Name('').GNode,见 _make_replacement_node/_make_name_node), - # 不是 ast.Name:此前只认 ast.Name → 方法形参漏加 | t.CPtr, - # 特化后按值结构体传参(被调者栈帧副本地址入链 → 悬垂写)。 - raw_name: str | None = self._BareClassAnnotationName(arg.annotation) - if raw_name is not None and raw_name in class_type_names: - arg.annotation = ast.BinOp( - left=arg.annotation, - op=ast.BitOr(), - right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load()) - ) - if item.returns: - item.returns = self.Trans.FunctionHandler._replace_type_in_annotation(item.returns, type_map, cptr_params) - # 返回类型也加指针语义(同一裸名判据,形态同上) - raw_name: str | None = self._BareClassAnnotationName(item.returns) - if raw_name is not None and raw_name in class_type_names: - item.returns = ast.BinOp( - left=item.returns, - op=ast.BitOr(), - right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load()) - ) - self.Trans.FunctionHandler._apply_type_map_to_body(item.body, type_map, cptr_params) - saved_builder: ir.IRBuilder = Gen.builder - saved_func: ir.Function = Gen.func - saved_variables: dict = dict(Gen.variables) if Gen.variables else {} - saved_direct_values: dict = dict(Gen._direct_values) if Gen._direct_values else {} - saved_var_type_info: dict = dict(Gen.var_type_info) if Gen.var_type_info else {} - saved_var_signedness: dict = dict(Gen.var_signedness) if Gen.var_signedness else {} - saved_global_vars: set = set(Gen.global_vars) if Gen.global_vars else set() - saved_var_scopes: list = [dict(s) for s in self.Trans.VarScopes] if self.Trans.VarScopes else [] - saved_block: ir.Block | None = None - if Gen.builder and Gen.builder.block and not Gen.builder.block.is_terminated: - saved_block = Gen.builder.block - # 切换 module_sha1 为泛型模板定义模块的 SHA1, - # 使结构体类型名和方法定义名都用定义模块的 SHA1 前缀, - # 与调用端 _struct_sha1_map 查到的 SHA1 一致。 - template_sha1: str | None = template.get('sha1') - if not template_sha1: - # 模板注册表缺 sha1 时回退到"模板类定义模块"(_struct_sha1_map 即 - # 类名 → 定义模块表,Phase2 从各 .vpi 扫描构建):与声明端 - # DeclarationGenerator._get_type_str 的泛型前缀、调用点 - # Gen._struct_sha1_map[spec_name] 同一条规则源;否则 declare/define - # 两侧前缀分裂(使用方模块 vs 模板模块)→ 跨模块 undefined symbol。 - template_sha1 = Gen._struct_sha1_map.get(ClassName) - saved_gen_sha1: str | None = getattr(Gen, 'module_sha1', None) - saved_trans_sha1: str | None = getattr(self.Trans, '_module_sha1', None) - if template_sha1: - Gen.module_sha1 = template_sha1 - self.Trans._module_sha1 = template_sha1 - try: - self._EmitClassLlvm(SpecNode, Gen, declare_only=declare_only) - finally: - # 确保 Gen 状态恢复,即使 _EmitClassLlvm 抛出异常 - Gen.builder = saved_builder - if saved_block is not None and Gen.builder is not None: - Gen.builder.position_at_end(saved_block) - Gen.func = saved_func - Gen.variables = saved_variables - Gen._direct_values = saved_direct_values - Gen.var_type_info = saved_var_type_info - Gen.var_signedness = saved_var_signedness - Gen.global_vars = saved_global_vars - self.Trans.VarScopes = saved_var_scopes - # 恢复原始 module_sha1 - Gen.module_sha1 = saved_gen_sha1 - self.Trans._module_sha1 = saved_trans_sha1 - Gen._generic_class_specializations[spec_key] = (spec_name, declare_only) - # 缓存 type_args/type_names,供后续 declare_only=False 完整特化补发方法体使用 - # (如 _HandleMethodCallLlvm 中发现方法未定义时触发) - if not hasattr(Gen, '_generic_class_spec_type_info'): - Gen._generic_class_spec_type_info = {} - Gen._generic_class_spec_type_info[spec_key] = (list(type_args), list(type_names) if type_names else None) - if not hasattr(self.Trans, '_generic_class_specializations'): - self.Trans._generic_class_specializations = {} - self.Trans._generic_class_specializations[spec_key] = spec_name - # 用模板定义模块的 SHA1 注册到 _struct_sha1_map,与方法定义端一致 - if template_sha1: - Gen._struct_sha1_map[spec_name] = template_sha1 - elif hasattr(self.Trans, '_module_sha1') and self.Trans._module_sha1: - Gen._struct_sha1_map[spec_name] = self.Trans._module_sha1 - return spec_name - def _resolve_base_kind(self, base_name: str, Gen: LlvmGeneratorMixin) -> str | None: """解析基类名称的类型种类 查询顺序: - 1. _t_type_symbols(from t import CEnum as en) - 2. t 模块属性(t.CEnum / t.CUnion / t.CStruct / t.REnum) + 1. _builtin_type_symbols(内建类型符号) + 2. TypeSystem 内建类型属性(CEnum / CUnion / CStruct / REnum) 3. 返回 None 表示不是已知标记基类 Returns: 'enum' | 'union' | 'renum' | 'struct' | None """ - # 1) 查 _t_type_symbols(别名导入) + # 1) 查 _builtin_type_symbols(别名导入) symtab: object = self.Trans.SymbolTable - cls: type | None = symtab._t_type_symbols.get(base_name) + cls: type | None = symtab._builtin_type_symbols.get(base_name) if cls is not None: - if issubclass(cls, (t.CEnum, t.REnum)): - return 'renum' if issubclass(cls, t.REnum) else 'enum' - if issubclass(cls, t.CUnion): + if issubclass(cls, (TypeSystem.CEnum, TypeSystem.REnum)): + return 'renum' if issubclass(cls, TypeSystem.REnum) else 'enum' + if issubclass(cls, TypeSystem.CUnion): return 'union' - if issubclass(cls, t.CStruct): + if issubclass(cls, TypeSystem.CStruct): return 'struct' # CType 及其子类(CChar/CInt/CVoid/CPtr 等)是"类型强转"标记, # 不应被编译为真实结构体。 - if issubclass(cls, t.CType): + if issubclass(cls, TypeSystem.CType): return 'ctype_marker' - # 2) 查 t 模块属性(直接引用 t.CEnum 等) - t_cls: type | None = getattr(t, base_name, None) - if isinstance(t_cls, type) and issubclass(t_cls, t.CType): - if issubclass(t_cls, (t.CEnum, t.REnum)): - return 'renum' if issubclass(t_cls, t.REnum) else 'enum' - if issubclass(t_cls, t.CUnion): + # 2) 查 TypeSystem 内建类型属性(直接引用 CEnum 等) + t_cls: type | None = getattr(TypeSystem, base_name, None) + if isinstance(t_cls, type) and issubclass(t_cls, TypeSystem.CType): + if issubclass(t_cls, (TypeSystem.CEnum, TypeSystem.REnum)): + return 'renum' if issubclass(t_cls, TypeSystem.REnum) else 'enum' + if issubclass(t_cls, TypeSystem.CUnion): return 'union' - if issubclass(t_cls, t.CStruct): + if issubclass(t_cls, TypeSystem.CStruct): return 'struct' # CType 及其子类是"类型强转"标记,不编译为结构体。 return 'ctype_marker' @@ -373,7 +271,7 @@ class ClassHandle(BaseHandle): @staticmethod def _is_classname_ctype_marker(class_name: str) -> bool: - """检查类名是否是 t.CType 的"类型强转"标记子类。 + """检查类名是否是 CType 的"类型强转"标记子类。 只有 position 不含 BASE 的纯修饰符/标记类型(CPtr/CVolatile/CConst/ CInline/CStatic/CExtern/CExport/CRegister/CAuto/_CTypedef/CTypeDefault 等) @@ -382,22 +280,22 @@ class ClassHandle(BaseHandle): 需要直接按类名检查。 注意:CTypeRegistry.GetClassByName 会跳过 CType 本身和 CTypeDefault, - 所以这里直接用 getattr(t, name) 检查 t 模块属性。 + 所以这里直接用 getattr(TypeSystem, name) 检查内建类型属性。 Returns: True 如果 class_name 是 CType 标记子类名(应跳过编译) """ if not class_name: return False - # 直接查 t 模块属性(CTypeRegistry._build 会跳过 CType/CTypeDefault/BigEndian/LittleEndian) - t_cls: type | None = getattr(t, class_name, None) - if not isinstance(t_cls, type) or not issubclass(t_cls, t.CType): + # 直接查 TypeSystem 内建类型属性(CTypeRegistry._build 会跳过 CType/CTypeDefault/BigEndian/LittleEndian) + t_cls: type | None = getattr(TypeSystem, class_name, None) + if not isinstance(t_cls, type) or not issubclass(t_cls, TypeSystem.CType): return False - if issubclass(t_cls, (t.CStruct, t.CEnum, t.REnum, t.CUnion)): + if issubclass(t_cls, (TypeSystem.CStruct, TypeSystem.CEnum, TypeSystem.REnum, TypeSystem.CUnion)): return False # 基本类型(position 含 BASE 且 Size > 0)有具体大小,不应跳过 # CVoid 虽含 BASE 但 Size=0,CType Size=None,仍需跳过 - if t.CType.BASE in t_cls.position: + if TypeSystem.CType.BASE in t_cls.position: try: inst = t_cls() size_val = getattr(inst, 'Size', None) @@ -410,8 +308,7 @@ class ClassHandle(BaseHandle): def _resolve_decorator_kind(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin) -> str | None: """从装饰器列表中解析结构体类型种类 - 支持 @t.CStruct, @t.CUnion, @t.CEnum, @t.REnum - 也支持 from t import CStruct 等别名形式 + 支持 @CStruct, @CUnion, @CEnum, @REnum(内建标记按裸名书写) Returns: 'enum' | 'union' | 'renum' | 'struct' | None @@ -421,32 +318,28 @@ class ClassHandle(BaseHandle): symtab: object = self.Trans.SymbolTable for decorator in Node.decorator_list: attr_name: str | None = None - # @t.CStruct 形式 - if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name): - if IsTModule(decorator.value.id, symtab): - attr_name = decorator.attr - # @CStruct 形式 (from t import CStruct) - elif isinstance(decorator, ast.Name): - cls: type | None = getattr(t, decorator.id, None) - if cls is None and hasattr(symtab, '_t_type_symbols'): - cls = symtab._t_type_symbols.get(decorator.id) - if cls is not None and isinstance(cls, type) and issubclass(cls, t.CType): + # 内建标记按裸名书写(@CStruct / @CUnion / ...) + if isinstance(decorator, ast.Name): + cls: type | None = getattr(TypeSystem, decorator.id, None) + if cls is None and hasattr(symtab, '_builtin_type_symbols'): + cls = symtab._builtin_type_symbols.get(decorator.id) + if cls is not None and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): attr_name = cls.__name__ if attr_name: - # 查 _t_type_symbols 和 t 模块属性以确定种类 + # 查 _builtin_type_symbols 和 TypeSystem 内建类型属性以确定种类 resolved_cls: type | None = None - if hasattr(symtab, '_t_type_symbols'): - resolved_cls = symtab._t_type_symbols.get(attr_name) + if hasattr(symtab, '_builtin_type_symbols'): + resolved_cls = symtab._builtin_type_symbols.get(attr_name) if resolved_cls is None: - resolved_cls = getattr(t, attr_name, None) + resolved_cls = getattr(TypeSystem, attr_name, None) if resolved_cls is not None and isinstance(resolved_cls, type): - if issubclass(resolved_cls, t.REnum): + if issubclass(resolved_cls, TypeSystem.REnum): return 'renum' - if issubclass(resolved_cls, t.CEnum): + if issubclass(resolved_cls, TypeSystem.CEnum): return 'enum' - if issubclass(resolved_cls, t.CUnion): + if issubclass(resolved_cls, TypeSystem.CUnion): return 'union' - if issubclass(resolved_cls, t.CStruct): + if issubclass(resolved_cls, TypeSystem.CStruct): return 'struct' return None @@ -466,15 +359,7 @@ class ClassHandle(BaseHandle): IsNoVTable: bool = False if hasattr(Node, 'decorator_list') and Node.decorator_list: for decorator in Node.decorator_list: - if isinstance(decorator, ast.Attribute): - if hasattr(decorator.value, 'id') and IsTModule(decorator.value.id, self.Trans.SymbolTable): - if decorator.attr == 'Object': - IsCpythonObject = True - elif decorator.attr == 'CVTable': - IsCVTable = True - elif decorator.attr == 'NoVTable': - IsNoVTable = True - elif isinstance(decorator, ast.Name): + if isinstance(decorator, ast.Name): if decorator.id == 'Object': IsCpythonObject = True elif decorator.id == 'CVTable': @@ -482,21 +367,21 @@ class ClassHandle(BaseHandle): elif decorator.id == 'NoVTable': IsNoVTable = True elif isinstance(decorator, ast.Call): - # 检测 @c.Attribute(t.attr.packed) - if isinstance(decorator.func, ast.Attribute): - if getattr(decorator.func.value, 'id', None) == 'c' and decorator.func.attr == 'Attribute': - for arg in decorator.args: - if isinstance(arg, ast.Attribute): - if isinstance(arg.value, ast.Attribute): - if IsTModule(getattr(arg.value.value, 'id', ''), self.Trans.SymbolTable) and arg.value.attr == 'attr' and arg.attr == 'packed': - Gen.class_packed.add(ClassName) + # 检测 @Attribute(attr.packed) + if isinstance(decorator.func, ast.Name) and decorator.func.id == 'Attribute': + for arg in decorator.args: + if (isinstance(arg, ast.Attribute) + and isinstance(arg.value, ast.Name) + and arg.value.id == 'attr' + and arg.attr == 'packed'): + Gen.class_packed.add(ClassName) class_graph: dict = Gen._class_graph if class_graph.get(ClassName, {}).get('has_methods', False) and not IsNoVTable: if not IsCpythonObject: IsCpythonObject = True # 多继承支持(与 VPC _detect_vtable_status 对齐):不再因"作为其他类的基类" # 自动启用 vtable。vtable 状态统一由继承链决定(见下方 HasParentClass 判定): - # 类自身无 @t.CVTable 时,父类有 vtable → 子类有;父类无 vtable → 子类静态。 + # 类自身无 @CVTable 时,父类有 vtable → 子类有;父类无 vtable → 子类静态。 # 否则基类(如 C(A,B) 中的 A/B)被自动加 vptr 后,其字段区在子类中的偏移 # 与自身布局不一致,继承方法按自身布局读 self 会字段错位。 HasParentClass: bool = False @@ -512,7 +397,7 @@ class ClassHandle(BaseHandle): base_name = base.attr if base_name: kind: str | None = self._resolve_base_kind(base_name, Gen) - if kind is not None or base_name in t._MARKER_BASES: + if kind is not None or base_name in TypeSystem._MARKER_BASES: continue # 标记基类,跳过 # 多继承:收集所有真实父类(声明顺序),不再 break ParentClasses.append(base_name) @@ -520,7 +405,7 @@ class ClassHandle(BaseHandle): ParentClassName = base_name if base_name in class_graph or base_name in Gen.class_members or base_name in Gen.structs: HasParentClass = True - # 检测父类是否有 @t.NoVTable 标记(非多态继承) + # 检测父类是否有 @NoVTable 标记(非多态继承) if class_graph.get(base_name, {}).get('has_novtable', False): ParentIsNoVTable = True # 跨模块父类:检查 _cross_module_novtable 集合 @@ -531,7 +416,7 @@ class ClassHandle(BaseHandle): # 父类有 vtable → 子类启用;父类无 vtable → 子类不启用(静态); # 父类 vtable 状态未知(跨模块/未注册)→ 保守启用。 # 沿继承链追溯父类的 vtable 状态(支持空中间基类 Stmt/ExprNode): - # Stmt/ExprNode 无方法但 @t.CVTable,跨模块加载时 _has_methods_prescan=False + # Stmt/ExprNode 无方法但 @CVTable,跨模块加载时 _has_methods_prescan=False # 未注册 class_vtable,若只查直接父类会误判子类为静态类 → # __before_init__ base=0 不写 vtable → 实例 vtable 为 null → 虚调用段错误。 # 修复:沿 class_parent 链向上查,任一祖先有 vtable 即判定子类有 vtable。 @@ -552,7 +437,7 @@ class ClassHandle(BaseHandle): or ParentClassName in Gen.structs) if parent_has_vtable or not parent_known: IsCVTable = True - # 方法级 virtual(`virtual def m(...)` ⇒ 方法装饰器 @t.CVTable)触发类级 vtable: + # 方法级 virtual(`virtual def m(...)` ⇒ 方法装饰器 @CVTable)触发类级 vtable: # 与 VPC ClassGenBase._detect_vtable_status 的三条 `_has_any_func_cvtable` # 分支逐条对齐(类级 NoVTable / 父类 NoVTable / 无真实父类)。 # 注意"父类已知且无 vtable" **不**触发(VPC 同分支返回 0)—— @@ -575,7 +460,7 @@ class ClassHandle(BaseHandle): ancestor_bases: list = ancestor_info.get('bases', []) next_ancestor: str | None = None for ab in ancestor_bases: - if ab not in t._MARKER_BASES and ab not in visited: + if ab not in TypeSystem._MARKER_BASES and ab not in visited: next_ancestor = ab break ancestor = next_ancestor @@ -661,14 +546,14 @@ class ClassHandle(BaseHandle): """ MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = NestedName - MemberNode.BaseType = t.CStruct(name=NestedName) + MemberNode.BaseType = TypeSystem.CStruct(name=NestedName) MemberNode.IsStruct = True self.Trans.SymbolTable.insert(NestedName, MemberNode) self.Trans.SymbolTable.insert(f'{ClassName}.{InnerName}', MemberNode) def _EmitClassLlvm(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin, declare_only: bool = False) -> None: ClassName: str = Node.name - # t.CType 及其子类(CChar/CInt/CVoid/CPtr/CTypeDefault 等)是"类型强转"标记, + # CType 及其子类(CChar/CInt/CVoid/CPtr/CTypeDefault 等)是"类型强转"标记, # 不应被编译为真实结构体。CType 基类本身无 bases,base 检测无法触发, # 此处在方法入口直接按类名跳过。 if self._is_classname_ctype_marker(ClassName): @@ -682,7 +567,7 @@ class ClassHandle(BaseHandle): IsCenum: bool = False IsCunion: bool = False IsRenum: bool = False - # 先检查装饰器形式(@t.CStruct / @t.CEnum / @t.CUnion / @t.REnum) + # 先检查装饰器形式(@CStruct / @CEnum / @CUnion / @REnum) deco_kind: str | None = self._resolve_decorator_kind(Node, Gen) if deco_kind == 'enum': IsCenum = True @@ -690,7 +575,7 @@ class ClassHandle(BaseHandle): IsCunion = True elif deco_kind == 'renum': IsRenum = True - # 再检查基类继承形式(class X(t.CStruct):),与装饰器合并 + # 再检查基类继承形式(class X(CStruct):),与装饰器合并 if not IsCenum and not IsCunion and not IsRenum and Node.bases: for base in Node.bases: base_name: str | None = None @@ -752,7 +637,7 @@ class ClassHandle(BaseHandle): if m.split('.')[-1] not in ('__new__', '__init__', '__before_init__') ] # 当前文件定义的类是权威定义,覆盖之前导入阶段可能添加的外部声明。 - # 关键:如果本地类是 @t.NoVTable 但同名导入类有 vtable(名称冲突), + # 关键:如果本地类是 @NoVTable 但同名导入类有 vtable(名称冲突), # 必须清除 vtable 状态,否则 _generate_structs 会错误添加 vtable 指针。 if IsNoVTable: Gen.class_vtable.discard(ClassName) @@ -1001,7 +886,7 @@ class ClassHandle(BaseHandle): # 由 HandlesImports.py:2647/2654 与 FuncGen.py:1057 触发;该分支不受 # "字段收集中"保护,见 HandlesImports.py:3299 的 `not force` 豁免)。 # 此时本循环后面的 `append` 会把**嵌套帧已经登记过的同一字段**再写一条 —— - # 现场:AST 的最后一个字段 `children: list[rawptr[AST]] | t.CPtr` 是全类唯一 + # 现场:AST 的最后一个字段 `children: list[rawptr[AST]] | CPtr` 是全类唯一 # 触发泛型特化的注解,处理它时嵌套帧重填了 AST 表(7 项),本循环恢复后 # 又追加一次 `children` ⇒ 表 8 项 / 去重 7 项,重名条目 `children@7`; # 该表又被祖先块展平**原样拷贝**给 AST 的每个子类(_FlattenInherited 只按 @@ -1033,7 +918,7 @@ class ClassHandle(BaseHandle): element_class: str | None = FindStructNameInAnnotationWithContext( item.annotation, self.Trans, Gen) # Fallback: FindStructNameInAnnotation 不处理 Subscript slice 为 BinOp 的情况 - # (如 list[AST | t.CPtr] | t.CPtr),使用 TypeInfo.Name 作为回退。 + # (如 list[AST | CPtr] | CPtr),使用 TypeInfo.Name 作为回退。 # TypeInfo.Name 由 _HandleSubscript 设置为特化名(如 'list[sha1.AST*]'), # 经 _MergeCTypeInfoInto 传播后保留。 if not element_class and TypeInfo.IsStruct and TypeInfo.Name and TypeInfo.Name in Gen.structs: @@ -1042,7 +927,7 @@ class ClassHandle(BaseHandle): if ClassName not in Gen.class_member_element_class: Gen.class_member_element_class[ClassName] = {} Gen.class_member_element_class[ClassName][VarName] = element_class - # 泛型特化结构体指针字段(如 GSList[BasicBlock] | t.CPtr): + # 泛型特化结构体指针字段(如 GSList[BasicBlock] | CPtr): # 记录特化名,供后续 _try_access_opaque_generic_member 在所有候选特化版本 # 都有目标字段(如 Head/Tail/Count)时选择正确特化版本。 # 现有 i8* 分支不覆盖结构体指针字段,这里补充。 @@ -1095,7 +980,7 @@ class ClassHandle(BaseHandle): else: # rawptr[裸结构](如 rawptr[Token]):跨模块 stub 会把自引用/类内 # 指针字段退化为 i8*,链式成员访问(a.b.c)需 element_class 恢复 - # struct 身份走 char*→struct cast。HEAD 态 `Token | t.CPtr` 联合 + # struct 身份走 char*→struct cast。HEAD 态 `Token | CPtr` 联合 # 由上方 BinOp 分支登记;rawptr 重构后此分支补齐(阻塞 A 根因)。 # 与 HandlesImports 的 rawptr 分支对称。 _slc_name_c: str | None = None @@ -1169,7 +1054,7 @@ class ClassHandle(BaseHandle): # `base + 表内下标`(FuncGen._get_member_offset)⇒ 落到**类型完全不同的槽**。 # 现场:TypeGenCType 重复声明 5 个父类已有字段后,继承字段 # LastBuiltinsTypedefResult(下标 32)前移为 27 = CTypedefNameIdxBuilt(i32) - # ⇒ `self.Gen.TypeGenCType.LastBuiltinsTypedefResult = "t.CPtr"` 报 + # ⇒ `self.Gen.TypeGenCType.LastBuiltinsTypedefResult = "CPtr"` 报 # "指针隐式转整数已禁止:不能把指针类型 i8* 赋给整数类型 i32"。 # ② 父类方法按**父类布局**访问该名字的槽、子类方法按**自有槽**访问 ⇒ 同名两槽 # split-brain(一侧写、另一侧读),运行期静默错值。 @@ -1255,8 +1140,8 @@ class ClassHandle(BaseHandle): # vtable 大小不一致导致虚分派索引偏移。__before_init__ 由 TPC # 自动生成,不会出现在 FunctionDef 中,此处一并防御。 # - # 方法级修饰符(`novirtual def m(...)` ⇒ @t.NoVTable / - # `virtual def m(...)` ⇒ @t.CVTable):是否占槽按 + # 方法级修饰符(`novirtual def m(...)` ⇒ @NoVTable / + # `virtual def m(...)` ⇒ @CVTable):是否占槽按 # SymbolUtils.IsVtableSlotMethod 判定——与 VPC # ClassGenBase._should_method_be_virtual 同判据(**唯一规则源**), # 故 TPC/VPC 的虚表槽位顺序与数量逐槽一致(含"类级 NoVTable + @@ -1596,7 +1481,7 @@ class ClassHandle(BaseHandle): f"`self.{VarName} = {_val_txt}` 的取值形态推不出成员类型" f"——拒绝静默当成 i32(那会把错误推到下游:写指针值时报" f"「指针隐式转整数已禁止」)。请在类体声明该字段并给注解" - f"(如 `{VarName}: t.CInt32T` / `{VarName}: t.CPtr`)," + f"(如 `{VarName}: CInt32T` / `{VarName}: CPtr`)," f"或在赋值处给出可定型的取值。" f"位置 {_src_f}:{_ln_f}:{_col_f}") _vlog().compile_error(_msg_f, _src_f, _ln_f, _code_f) @@ -1664,18 +1549,18 @@ class ClassHandle(BaseHandle): variant_names: list[str] = [] # 预注册 REnum opaque 结构体到 Gen.structs 和 SymbolTable, - # 使自引用成员(如 LLVMType | t.CPtr)在收集成员时能正确解析为 %LLVMType*。 - # 若不预注册,GetCTypeInfo 找不到 LLVMType → 回退到 IsEnum → i32 → | t.CPtr → i32*(错误)。 + # 使自引用成员(如 LLVMType | CPtr)在收集成员时能正确解析为 %LLVMType*。 + # 若不预注册,GetCTypeInfo 找不到 LLVMType → 回退到 IsEnum → i32 → | CPtr → i32*(错误)。 PreRenumType: ir.IdentifiedStructType = ir.IdentifiedStructType(Gen.module, ClassName) Gen.structs[ClassName] = PreRenumType PreTypeInfo: CTypeInfo = CTypeInfo() PreTypeInfo.Name = ClassName - PreTypeInfo.BaseType = t.REnum(ClassName) + PreTypeInfo.BaseType = TypeSystem.REnum(ClassName) PreTypeInfo.IsRenum = True PreTypeInfo.IsEnum = True # REnum 在内存布局上是 struct({ i32 __tag, }), # 必须设置 IsStruct=True 才能让 HandlesTypeMerge 的 CPtr 吸收逻辑生效: - # `REnumType | t.CPtr` 应得到 REnumType*(PtrCount=1)而非 REnumType**(PtrCount=2)。 + # `REnumType | CPtr` 应得到 REnumType*(PtrCount=1)而非 REnumType**(PtrCount=2)。 # 否则 include-imported 函数返回类型会出现双指针,与声明单指针不匹配 → 运行时崩溃。 PreTypeInfo.IsStruct = True PreTypeInfo.RenumVariants = [] @@ -1795,7 +1680,7 @@ class ClassHandle(BaseHandle): Gen.class_member_signeds[NestedStructName][mname] = None MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = VariantName - MemberNode.BaseType = t.CEnum(ClassName) + MemberNode.BaseType = TypeSystem.CEnum(ClassName) MemberNode.value = tag_value MemberNode.EnumName = ClassName MemberNode.Lineno = lineno @@ -1814,9 +1699,9 @@ class ClassHandle(BaseHandle): 与 VPC 侧 ClassGenEnum._enum_member_annotation_is_ptr 同口径。枚举值是 整数常量,指针成员语义不成立,必须明确报错(fail-fast)而非静默接受: - 此前 TPC 完全忽略成员注解,`Name: t.CPtr` 会被当成普通 i32 成员放行。 - 指针标记既按名字匹配(含 str/bytes = i8*、rawptr = t.CPtr),也按 - from t import CPtr as P 这类别名经 _t_type_symbols 还原后判定。 + `Name: CPtr` 不能被当成普通 i32 成员放行。 + 指针标记既按名字匹配(含 str/bytes = i8*、rawptr = CPtr),也按 + _builtin_type_symbols 中的内建类型符号判定。 """ if annotation is None: return False @@ -1836,11 +1721,11 @@ class ClassHandle(BaseHandle): return True symtab: object = self.Trans.SymbolTable resolved: type | None = None - if hasattr(symtab, '_t_type_symbols'): - resolved = symtab._t_type_symbols.get(name) + if hasattr(symtab, '_builtin_type_symbols'): + resolved = symtab._builtin_type_symbols.get(name) if resolved is None: - resolved = getattr(t, name, None) - if isinstance(resolved, type) and issubclass(resolved, t.CPtr): + resolved = getattr(TypeSystem, name, None) + if isinstance(resolved, type) and issubclass(resolved, TypeSystem.CPtr): return True return False @@ -1885,7 +1770,7 @@ class ClassHandle(BaseHandle): EnumWidth: int = self._EnumClassIntWidth(Node) EnumTypeInfo: CTypeInfo = CTypeInfo() EnumTypeInfo.Name = ClassName - EnumTypeInfo.BaseType = t.CEnum(ClassName) + EnumTypeInfo.BaseType = TypeSystem.CEnum(ClassName) EnumTypeInfo.IsEnum = True EnumTypeInfo.set('enum_width', EnumWidth) self.Trans.SymbolTable.insert(ClassName, EnumTypeInfo) @@ -1922,7 +1807,7 @@ class ClassHandle(BaseHandle): next_enum_value += 1 MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = VarName - MemberNode.BaseType = t.CEnum(ClassName) + MemberNode.BaseType = TypeSystem.CEnum(ClassName) MemberNode.value = value MemberNode.EnumName = ClassName MemberNode.Lineno = item.lineno @@ -1938,7 +1823,7 @@ class ClassHandle(BaseHandle): elif isinstance(item, ast.AnnAssign): if isinstance(item.target, ast.Name): VarName = item.target.id - # [枚举规格 fail-fast] 成员不允许指针类型(t.CPtr 家族 / + # [枚举规格 fail-fast] 成员不允许指针类型(CPtr 家族 / # rawptr[...] / str / bytes / 联合里夹带指针)——此前成员注解 # 被整体忽略,指针成员被静默当 i32 放行。 if self._EnumMemberAnnotationIsPtr(item.annotation): @@ -1971,7 +1856,7 @@ class ClassHandle(BaseHandle): next_enum_value += 1 MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = VarName - MemberNode.BaseType = t.CEnum(ClassName) + MemberNode.BaseType = TypeSystem.CEnum(ClassName) MemberNode.value = value MemberNode.EnumName = ClassName MemberNode.Lineno = item.lineno diff --git a/lib/core/Handles/HandlesDelete.py b/lib/core/Handles/HandlesDelete.py index e462dcc..d2f2fed 100644 --- a/lib/core/Handles/HandlesDelete.py +++ b/lib/core/Handles/HandlesDelete.py @@ -17,7 +17,7 @@ class DeleteHandle(BaseHandle): obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target.value) idx_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target.slice) if obj_val and idx_val: - # 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8 + # 处理 obj_val 为 i8(整数)的情况:联合类型 | CPtr 降级后可能被 load 为 i8 if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8: obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}") if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.IntType) and obj_val.type.pointee.width == 8: @@ -28,7 +28,7 @@ class DeleteHandle(BaseHandle): if ClassName and Gen._has_function(f'{ClassName}.__delete__'): obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target) if obj_val: - # 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8 + # 处理 obj_val 为 i8(整数)的情况:联合类型 | CPtr 降级后可能被 load 为 i8 if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8: obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}") if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.IntType) and obj_val.type.pointee.width == 8: diff --git a/lib/core/Handles/HandlesExpr.py b/lib/core/Handles/HandlesExpr.py index 3ed9a31..bf9044e 100644 --- a/lib/core/Handles/HandlesExpr.py +++ b/lib/core/Handles/HandlesExpr.py @@ -8,7 +8,7 @@ import re import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle from lib.constants.config import mode as _config_mode -from lib.includes.t import CTypeRegistry as _CR +from lib.core.TypeSystem import CTypeRegistry as _CR from lib.core.SymbolUtils import (RequireDefineUseWidthAt, RequireIntLiteralStorable, RequireNameDefined, RequireExplicitWidthLiteral, DefineDeclTypeValue, GlobalDeclShadowsDefine) @@ -234,7 +234,7 @@ class ExprHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:数组字面量第 {i} 个元素是指针类型 {elem_val.type}," - f"但目标元素类型是 i8;如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"但目标元素类型是 i8;如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{Gen._DescribeValueNode(elem)}" ) elif elem_type == 'i32': @@ -249,7 +249,7 @@ class ExprHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:数组字面量第 {i} 个元素是指针类型 {elem_val.type}," - f"但目标元素类型是 i32;如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"但目标元素类型是 i32;如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{Gen._DescribeValueNode(elem)}" ) elif elem_type == 'i16': @@ -415,7 +415,7 @@ class ExprHandle(BaseHandle): Gen: LlvmCodeGenerator = self.Trans.LlvmGen VarName: str = Node.id # 治本修复:不把 module.globals 的 initializer 注入 _define_constants。 - # 原因:CDefine(t.CDefine 注解)在 AnnAssign/Assign 处理时已注册到 + # 原因:CDefine(CDefine 注解)在 AnnAssign/Assign 处理时已注册到 # _define_constants 且不创建 LLVM global(不在 module.globals); # module.globals 里全是可变全局变量(如 _sha1_store_count,有 += 写入), # 若把其 initializer 当常量传播,会导致 range(_sha1_store_count) 被求值成 @@ -604,7 +604,7 @@ class ExprHandle(BaseHandle): if isinstance(g, ir.Function): Gen.functions[VarName] = g return Gen.builder.bitcast(g, ir.IntType(8).as_pointer(), name=f"funcptr_{VarName}") - t_c_imported: dict[str, tuple[str, str]] = getattr(self.Trans, '_t_c_imported_names', {}) + t_c_imported: dict[str, tuple[str, str]] = getattr(self.Trans, '_from_import_aliases', {}) if VarName in t_c_imported: src_module: str src_name: str diff --git a/lib/core/Handles/HandlesExprAsm.py b/lib/core/Handles/HandlesExprAsm.py index 53f222a..384ce53 100644 --- a/lib/core/Handles/HandlesExprAsm.py +++ b/lib/core/Handles/HandlesExprAsm.py @@ -7,8 +7,7 @@ if TYPE_CHECKING: from lib.core.translator import Translator from lib.core.LlvmCodeGenerator import LlvmCodeGenerator from lib.core.Handles.HandlesBase import BaseHandle -from lib.core.SymbolUtils import IsTModule -from lib.includes import t +from lib.core import TypeSystem # --------------------------------------------------------------- # asm 模板重写用的正则**预编译**(性能:避免每次 `re.sub(字面量, ...)` 都要做 @@ -212,14 +211,16 @@ class ExprAsmHandle(BaseHandle): def _intrinsic_marker(expr: ast.AST) -> str | None: """识别内建操作数标记调用,返回规范名或 None - 支持两种等价写法(裸名写法省去 c. 前缀): - - 内联汇编:c.AsmInp / c.AsmOut ↔ asminp / asmout - - LLVM IR:c.LInp / c.LOut ↔ irinp / irout + 规范名为裸名写法: + - 内联汇编:AsmInp / AsmOut(小写 asminp / asmout 等价) + - LLVM IR:LInp / LOut(小写 irinp / irout 等价) """ if not isinstance(expr, ast.Call): return None func: ast.AST = expr.func if isinstance(func, ast.Name): + if func.id in ('AsmInp', 'AsmOut', 'LInp', 'LOut'): + return func.id if func.id == 'asminp': return 'AsmInp' if func.id == 'asmout': @@ -229,11 +230,6 @@ class ExprAsmHandle(BaseHandle): if func.id == 'irout': return 'LOut' return None - if isinstance(func, ast.Attribute): - if isinstance(func.value, ast.Name) and func.value.id == 'c': - if func.attr in ('AsmInp', 'AsmOut', 'LInp', 'LOut'): - return func.attr - return None return None def _process_joined_str_template(self, node: ast.AST, out_input_ops: list[Any], out_input_constraints: list[str], @@ -281,8 +277,7 @@ class ExprAsmHandle(BaseHandle): out_output_constraints.append(c) raw_parts.append(('output', len(out_output_ops) - 1)) elif not (isinstance(expr, ast.Call) and isinstance(expr.func, ast.Attribute)): - # 非 c.* 属性调用的表达式按普通输入操作数处理(保持原行为: - # c.* 属性调用中非 AsmInp/AsmOut 的形态不收集) + # 非标记的属性调用不收集,其余表达式按普通输入操作数处理 fallback: Any = self.HandleExprLlvm(expr) if fallback and isinstance(fallback.type, ir.IntType): out_input_ops.append(fallback) @@ -583,16 +578,10 @@ class ExprAsmHandle(BaseHandle): return left_val + right_val elif isinstance(expr, ast.Attribute): - if isinstance(expr.value, ast.Attribute): - if (isinstance(expr.value.value, ast.Name) and - IsTModule(expr.value.value.id, self.Trans.SymbolTable) and - expr.value.attr == 'ASM_DESCR'): - AttrName: str = expr.attr - return getattr(t.ASM_DESCR, AttrName, "") - elif isinstance(expr.value, ast.Name) and (expr.value.id == 'ASM_DESCR' or IsTModule(expr.value.id, self.Trans.SymbolTable)): - # 裸名 ASM_DESCR.XXX:省去 t. 前缀的等价写法 + if isinstance(expr.value, ast.Name) and expr.value.id == 'ASM_DESCR': + # 裸名 ASM_DESCR.XXX AttrName: str = expr.attr - return getattr(t.ASM_DESCR, AttrName, "") + return getattr(TypeSystem.ASM_DESCR, AttrName, "") elif isinstance(expr, ast.Constant): return expr.value @@ -602,9 +591,9 @@ class ExprAsmHandle(BaseHandle): def _infer_expr_llvm_type(self, expr: ast.AST) -> ir.Type | None: if isinstance(expr, ast.Name): type_name: str = expr.id - if hasattr(t, type_name): - ctype: Any = getattr(t, type_name) - if isinstance(ctype, type) and issubclass(ctype, t.CType): + if hasattr(TypeSystem, type_name): + ctype: Any = getattr(TypeSystem, type_name) + if isinstance(ctype, type) and issubclass(ctype, TypeSystem.CType): size: Any = getattr(ctype, 'Size', None) if size is not None: return ir.IntType(size) @@ -613,6 +602,6 @@ class ExprAsmHandle(BaseHandle): elif type_name == 'CDouble': return ir.DoubleType() elif isinstance(expr, ast.Attribute): - if isinstance(expr.value, ast.Name) and IsTModule(expr.value.id, self.Trans.SymbolTable): + if isinstance(expr.value, ast.Name) : return self._infer_expr_llvm_type(ast.Name(id=expr.attr, ctx=ast.Load())) return None diff --git a/lib/core/Handles/HandlesExprAttr.py b/lib/core/Handles/HandlesExprAttr.py index 6ebf997..6aa55b3 100644 --- a/lib/core/Handles/HandlesExprAttr.py +++ b/lib/core/Handles/HandlesExprAttr.py @@ -459,8 +459,8 @@ class ExprAttrHandle(BaseHandle): """模块限定全局读取归一化:类指针全局的「多一层」元素类型还原为对象指针 `Mod.g`(g 为模块级全局)的取值统一经 _lookup_module_global:注解为 - `X | t.CPtr` 的模块级全局(如 GenApi._g_gen: rawptr[Generator.Generator]、 - VLogger.logger: Logger | t.CPtr)在本编译器里物化成「比对象多一层」的 + `X | CPtr` 的模块级全局(如 GenApi._g_gen: rawptr[Generator.Generator]、 + VLogger.logger: Logger | CPtr)在本编译器里物化成「比对象多一层」的 元素类型 T**(写入端见 main.vp `GenApi._g_gen = gen`:bitcast T*→T** 后 直接存值,未取地址)⇒ 其位形就是对象指针 T*,静态类型多了一层。 裸名形态(`g.Field`)由 _handle_attr_name 的既有同款补偿 bitcast 处理; @@ -471,7 +471,7 @@ class ExprAttrHandle(BaseHandle): 调用接收者 None 而静默丢调用(VpiReader.vp:4066 `GenApi._g_gen.ClassGenBase._collect_parents(...)`)。此处做同款逆运算: 只改静态类型、不改位形(bitcast 不产指令)。 - 判据限定「pointee 仍是指向结构体的指针」⇒ `str | t.CPtr` 一类真双层指针 + 判据限定「pointee 仍是指向结构体的指针」⇒ `str | CPtr` 一类真双层指针 全局(@_argv / @_g_pyi_cdef_names = i8**,实参直传 i8** 形参)不受影响。 """ if not isinstance(Val, ir.Value) or not isinstance(Val.type, ir.PointerType): @@ -1283,13 +1283,11 @@ class ExprAttrHandle(BaseHandle): def _handle_attr_call_result(self, Node: ast.Attribute) -> ir.Value | None: """处理 func().attr 属性访问""" Gen: LlvmCodeGenerator = self.Trans.LlvmGen - # Check if this is c.Deref(...) — we need the pointer, not the Loaded value + # Check if this is Deref(...) — we need the pointer, not the Loaded value ObjVal: Any = None is_cderef: bool = (isinstance(Node.value, ast.Call) and - isinstance(Node.value.func, ast.Attribute) and - isinstance(Node.value.func.value, ast.Name) and - Node.value.func.value.id == 'c' and - Node.value.func.attr == 'Deref' and + isinstance(Node.value.func, ast.Name) and + Node.value.func.id == 'Deref' and Node.value.args) if is_cderef: deref_arg: ast.expr = Node.value.args[0] @@ -1301,15 +1299,15 @@ class ExprAttrHandle(BaseHandle): ObjVal = inner_val if ObjVal is None: ObjVal = self.HandleExprLlvm(Node.value) - # 联合类型转换 (X | t.CPtr)(arg) 的属性访问(治本修复): + # 联合类型转换 (X | CPtr)(arg) 的属性访问(治本修复): # TPC 联合转换对非 CType 类(如 ast.Name / ast.Call)目标类型解析失败, # 结果可能退回 Ptr(i8) 或错误类型,导致下方 find_struct_by_pointee 失败、 - # 属性访问被静默丢弃——((ast.Name|t.CPtr)(ov)).id 编译后 store 0 次 + # 属性访问被静默丢弃——((ast.Name|CPtr)(ov)).id 编译后 store 0 次 # (with 语句 asname 未绑定、pool 未定义根因)。从联合 BinOp 提取真实 # 基础类并 bitcast 到 Ptr(类) 再访问成员。 # # 该形态的每个 return None 都改成 fail-fast(见 _FailFastAttrCallBase): - # `(T | t.CPtr)(x)` 只可能来自指针强转(parser 把 `(T*)x` / `T*(x)` 统一 + # `(T | CPtr)(x)` 只可能来自指针强转(parser 把 `(T*)x` / `T*(x)` 统一 # 产成该 Call),返回 None 会让调用方只报"表达式编译期求值为空",看不出是 # 类名没被当成类、结构体不透明、还是成员偏移取不到(现场:ViperC # ExprGenBase.vp:360 `v = (ast.Expr*(node)).value`,而同一函数前三条 @@ -1370,9 +1368,9 @@ class ExprAttrHandle(BaseHandle): def _FailFastAttrCallBase(self, Stage: str, Node: ast.Attribute, Gen: Any, IsUnionCastBase: bool, UnionCls: str | None, ObjVal: Any) -> None: - """`(T | t.CPtr)(x).attr` 属性访问失败时的 fail-fast(非该形态时静默返回,行为不变)。 + """`(T | CPtr)(x).attr` 属性访问失败时的 fail-fast(非该形态时静默返回,行为不变)。 - `(T | t.CPtr)(x)` 只可能来自指针强转(parser 把 `(T*)x` / `(T*)(x)` / `T*(x)` + `(T | CPtr)(x)` 只可能来自指针强转(parser 把 `(T*)x` / `(T*)(x)` / `T*(x)` 统一产成该 Call),其属性访问必须有值产出。此前一律 `return None`,调用方只能 报"赋值表达式 'value'(Attribute 形态)编译期求值为空",把"类名没被当成类 / 结构体不透明 / 成员偏移取不到"三种完全不同的根因混成一条报文 @@ -1427,10 +1425,10 @@ class ExprAttrHandle(BaseHandle): return f"<查询异常 {type(_E).__name__}: {_E}>" def _extract_union_base_class(self, NodeFunc: ast.BinOp) -> str | None: - """从 (X | t.CPtr) 联合 BinOp 提取第一个非指针/非修饰符的类名 + """从 (X | CPtr) 联合 BinOp 提取第一个非指针/非修饰符的类名 X 可以是任意类(如 ast.Name / ast.Call / memhub.MemPool),不限于 - t.CType 子类——联合转换 (X | t.CPtr)(arg) 的属性访问需要真实类名 + CType 子类——联合转换 (X | CPtr)(arg) 的属性访问需要真实类名 才能 bitcast 到 Ptr(类) 并定位成员偏移。 """ if not isinstance(NodeFunc, ast.BinOp) or not isinstance(NodeFunc.op, ast.BitOr): @@ -1528,7 +1526,7 @@ class ExprAttrHandle(BaseHandle): if isinstance(Node.value, ast.Name): VarName: str = Node.value.id # 处理 t/c import 的别名重定向 - t_c_imported: Any = getattr(self.Trans, '_t_c_imported_names', {}) + t_c_imported: Any = getattr(self.Trans, '_from_import_aliases', {}) if VarName != 'self' and VarName in t_c_imported: src_module: str src_name: str @@ -1561,7 +1559,7 @@ class ExprAttrHandle(BaseHandle): def _HandleSubscriptLlvm(self, Node: ast.Subscript) -> ir.Value | None: Gen: LlvmCodeGenerator = self.Trans.LlvmGen - # pointee-volatile(rawptr[t.CVolatile | T])基址:下标 GEP 名带基址名, + # pointee-volatile(rawptr[CVolatile | T])基址:下标 GEP 名带基址名, # 顶层 _load/_store 经 BaseGen._IsPtrVolatile 回查登记名,使其 load/store # 带 LLVM volatile。基址名取不到时后缀为空 ⇒ GEP 名仍是 "subscript", # 既有代码 IR 逐字节不变。 @@ -1575,7 +1573,7 @@ class ExprAttrHandle(BaseHandle): obj_val: Any = self.HandleExprLlvm(Node.value) idx_val: Any = self.HandleExprLlvm(Node.slice) if obj_val and idx_val: - # 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8 + # 处理 obj_val 为 i8(整数)的情况:联合类型 | CPtr 降级后可能被 load 为 i8 # 需要先 inttoptr 转换为 i8*,再 bitcast 到目标 struct 指针 if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8: obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}") @@ -1609,13 +1607,13 @@ class ExprAttrHandle(BaseHandle): ptr: Any = Gen.builder.gep(i8_ptr, [IndexVal], name="int_subscript_ptr") return Gen._load(ptr, name="int_subscript_val") return None - # 当变量本身是二级指针(如 elem_ptr: T | t.CPtr = AST**), + # 当变量本身是二级指针(如 elem_ptr: T | CPtr = AST**), # 但 HandleExprLlvm 已自动 load 返回 AST*(一级指针), # 需要检查 Gen.variables 中的原始 alloca 类型, # 若是二级指针且存储的是结构体指针,应 bitcast ValueVal 为 AST** 后 GEP 再 load, # 避免 GEP AST 结构体数组返回错误的 AST*(指向存储位置而非实际对象)。 - # 仅当 var_ptr_element 标记为 True 时触发(由 AnnAssign 检测 (S|t.CPtr)|t.CPtr 注解设置), - # 防止 pts: Point | t.CPtr(简单结构体指针)错误走二级指针路径。 + # 仅当 var_ptr_element 标记为 True 时触发(由 AnnAssign 检测 (S|CPtr)|CPtr 注解设置), + # 防止 pts: Point | CPtr(简单结构体指针)错误走二级指针路径。 if (isinstance(Node.value, ast.Name) and isinstance(ValueVal.type, ir.PointerType) and isinstance(ValueVal.type.pointee, (ir.IdentifiedStructType, ir.LiteralStructType))): @@ -1659,7 +1657,7 @@ class ExprAttrHandle(BaseHandle): return self._load_arr_elem_with_bswap(Gen, ElemPtr, arr_byte_order) else: if isinstance(pointee, ir.IntType) and pointee.width == 8: - # 指针槽变量优先(8fbba 修复):T|t.CPtr 指针槽(elem_ptr 指向 + # 指针槽变量优先(8fbba 修复):T|CPtr 指针槽(elem_ptr 指向 # 8 字节指针数组,如 _list.vp 泛型方法体)→ i8** load i8*。 # 必须放在 _infer_element_struct_class 之前——泛型 T 未解析时 # var_struct_class 误注册 llvmlite.Value,若先推断 elem_class @@ -1682,7 +1680,7 @@ class ExprAttrHandle(BaseHandle): if isinstance(pointee, ir.IntType): return self._load_arr_elem_with_bswap(Gen, ElemPtr, arr_byte_order) return ElemPtr - # 指针到 str/bytes 的变量 (BinOp 注解如 str | t.CPtr) + # 指针到 str/bytes 的变量 (BinOp 注解如 str | CPtr) # elem_ptr 是 i8* 但实际指向 i8* (字符串指针), elem_ptr[0] 应加载 8 字节 if isinstance(Node.value, ast.Name): _ptr_elem_flag = (getattr(Gen, 'var_ptr_element', {}).get(Node.value.id, False) @@ -1795,7 +1793,7 @@ class ExprAttrHandle(BaseHandle): ElemPtr = Gen.builder.gep(ValueVal, [IndexVal], name=f"subscript_ptr{_PVSuffix}") return ElemPtr else: - # 指针到 str/bytes 的变量 (BinOp 注解如 str | t.CPtr, bytes | t.CPtr) + # 指针到 str/bytes 的变量 (BinOp 注解如 str | CPtr, bytes | CPtr) # elem_ptr 是 i8* 但实际指向 i8* (指针数组), 应按 8 字节步长 GEP if isinstance(Node.value, ast.Name): _ptr_elem_flag: bool = (getattr(Gen, 'var_ptr_element', {}).get(Node.value.id, False) @@ -2015,7 +2013,7 @@ class ExprAttrHandle(BaseHandle): return MemberPtr elif isinstance(Node.value, ast.Call): # 指针强转基座(`(ast.Call*(vinner)).IsVolatile = 1`):`T*(x)` 被 vast 的 - # _ConsumePtrSuffixCall 解析为 `(T | t.CPtr)(x)` 强转调用,结果类型是联合 + # _ConsumePtrSuffixCall 解析为 `(T | CPtr)(x)` 强转调用,结果类型是联合 # 简化后的 i8*(struct 身份丢失),故须从强转注解(func 是 BitOr 联合) # 提真实类名,bitcast/inttoptr 回 Ptr(类) 后 GEP 成员。 # 与读取侧 _handle_attr_call_result 的联合分支(_extract_union_base_class) diff --git a/lib/core/Handles/HandlesExprBuiltin.py b/lib/core/Handles/HandlesExprBuiltin.py index 6a71e1a..bab40b9 100644 --- a/lib/core/Handles/HandlesExprBuiltin.py +++ b/lib/core/Handles/HandlesExprBuiltin.py @@ -8,17 +8,14 @@ import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode -from lib.includes.t import CTypeRegistry -from lib.includes import t as _t -from lib.core.SymbolUtils import IsTModule - - +from lib.core.TypeSystem import CTypeRegistry +from lib.core import TypeSystem as _t # len() 参数形态不支持时的共享提示语(与 ViperC App/lib/core/Gen/Call/ # CallGenDispatch.vp 的 len() 分支同口径,措辞逐字一致,便于用户对照两侧报文)。 _LEN_SUPPORTED_HINT: str = ( - "len() 只支持定长数组/数组指针(t.CArray[T, N])、i8*(str/bytes)或带 __len__ 的结构体;" + "len() 只支持定长数组/数组指针(CArray[T, N])、i8*(str/bytes)或带 __len__ 的结构体;" "非 i8 裸指针/标量指针没有长度语义:字符串请用 str/bytes,需要元素个数请自行记录长度," - "或改用 t.CPtr[元素] 并显式维护元素计数" + "或改用 CPtr[元素] 并显式维护元素计数" ) @@ -48,9 +45,9 @@ class ExprBuiltinHandle(BaseHandle): return None FuncName: str = Node.func.id - # Two-arg scalar alias form (int(v, t.CPtr) / char / bool / float / double) + # Two-arg scalar alias form (int(v, CPtr) / char / bool / float / double) # is a pointer wrap, not a scalar cast: route it to the same exit as the - # attribute form t.CInt(v, t.CPtr). Ignoring the CPtr mark would degrade + # attribute form CInt(v, CPtr). Ignoring the CPtr mark would degrade # it to a bare trunc, e.g. includes/argparse.vp get_bool() reading a # pointer's low 32 bits instead of the stored value. if (len(Node.args) >= 2 and FuncName in ('int', 'char', 'bool', 'float', 'double') @@ -106,7 +103,7 @@ class ExprBuiltinHandle(BaseHandle): return ir.Constant(ir.IntType(32), 0) elif FuncName == 'char': # char(x) → i8(与 int()/bool()/float()/double() 并列的内建标量强转; - # char = t.CChar = i8) + # char = CChar = i8) if Node.args: Val = self.HandleExprLlvm(Node.args[0]) if Val: @@ -184,7 +181,7 @@ class ExprBuiltinHandle(BaseHandle): str_val = Gen.builder.call(Gen._get_function(f'{ClassName}.__str__'), [arg_val], name=f"call_{ClassName}.__str__") return str_val return arg_val - # str 是类型名(= t.CChar* = i8*),str(x) ≡ (str)(x) 类型转换: + # str 是类型名(= CChar* = i8*),str(x) ≡ (str)(x) 类型转换: # 整型(u64/sizet 地址、char 码)→ inttoptr,与 VPC # CallGenDispatch._tc_h3_stdarg_cast 的 str 分支同语义 # (CallGenCtor._translate_t_type_cast 的「整数 → 指针: inttoptr」)。 @@ -194,7 +191,7 @@ class ExprBuiltinHandle(BaseHandle): return Gen.builder.inttoptr(arg_val, ir.IntType(8).as_pointer(), name="str_int2ptr") return ir.Constant(ir.IntType(8).as_pointer(), None) elif FuncName == 'bytes': - # bytes() — 类型转换为 i8* 指针 (等同于 t.CPtr / str) + # bytes() — 类型转换为 i8* 指针 (等同于 CPtr / str) # bytes(int_addr) → inttoptr; bytes(ptr) → bitcast if Node.args: arg_val = self.HandleExprLlvm(Node.args[0]) @@ -366,7 +363,7 @@ class ExprBuiltinHandle(BaseHandle): """运行时:读对象头部 vtable 指针,与集合中每个 vtable 地址比较""" ObjPtr: ir.Value = ObjVal if isinstance(ObjVal.type, ir.PointerType) and isinstance(ObjVal.type.pointee, ir.PointerType): - # 二级指针(变量 alloca / 联合 Class|t.CPtr)→ 先 load 出对象指针 + # 二级指针(变量 alloca / 联合 Class|CPtr)→ 先 load 出对象指针 ObjPtr = Gen._load(ObjVal, name="isinstance_load") if not isinstance(ObjPtr.type, ir.PointerType): return self._IsinstanceCompileTime(Gen, ObjVal, '') @@ -562,8 +559,6 @@ class ExprBuiltinHandle(BaseHandle): if isinstance(arg_node, ast.Call): if isinstance(arg_node.func, ast.Name): return arg_node.func.id in ('CChar', 'CUInt8T', 'CInt8T') - if isinstance(arg_node.func, ast.Attribute): - return arg_node.func.attr in ('CChar', 'CUInt8T', 'CInt8T') return False def _is_val_unsigned(self, arg_node: ast.AST, val: ir.Value) -> bool: @@ -667,7 +662,7 @@ class ExprBuiltinHandle(BaseHandle): offset = Gen._get_member_offset(len_member, bare_cls, _STl) len_ptr = Gen.builder.gep(self_ptr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=f"{obj_name}_{len_member}_ptr") return Gen._load(len_ptr, name=f"{obj_name}_{len_member}") - # 修复 stdint.vp 崩溃(0xC0000005)根因:`list[X] | t.CPtr` 联合字段 + # 修复 stdint.vp 崩溃(0xC0000005)根因:`list[X] | CPtr` 联合字段 # 的 LLVM 类型退化为 i8*,_HandleLenLlvm 无法识别为 list,fall through # 到 strlen 分支 → 对 list 对象指针执行 strlen → 垃圾长度 → 越界 get # → 垃圾指针 → strcmp 崩。此处按字段静态类型(class_member_element_class @@ -818,7 +813,7 @@ class ExprBuiltinHandle(BaseHandle): elif isinstance(Node, ast.Attribute): type_name = Node.attr else: - # 非 名称/属性 的 sizeof 目标(如 sizeof(a + b)、sizeof(t.CArray[int,4])): + # 非 名称/属性 的 sizeof 目标(如 sizeof(a + b)、sizeof(CArray[int,4])): # 曾静默返回 0 → 下游 alloc(0) 返回 NULL。fail-fast。 raise ValueError( f"[FATAL][__sizeof__] sizeof 的目标 {type(Node).__name__}" @@ -1193,9 +1188,9 @@ class ExprBuiltinHandle(BaseHandle): 解析顺序(与注解解析同一规则源,避免各处手抄一份而漏项): 1) str/bytes/CPtr → i8*;类名(Gen.structs)→ 该类指针 - 2) CTypeRegistry.GetClassByName/ResolveName(t.* 类型类与 C 基本类型名) + 2) CTypeRegistry.GetClassByName/ResolveName(CType 类型类与 C 基本类型名) 3) CTypeInfo.FromNode:builtins/库/符号表 typedef(uint64/int64/sizet/ - size_t…)、`T*` 指针后缀(parser 已展开为 `T | t.CPtr`)等 + size_t…)、`T*` 指针后缀(parser 已展开为 `T | CPtr`)等 fail-fast:以上均解析不出 LLVM 类型时直接报错终止,**绝不回退 i32**。 回退 i32 的后果不是"精度差一点"而是**读错变参槽**:Win64 变参槽固定 8 字节, @@ -1236,16 +1231,7 @@ class ExprBuiltinHandle(BaseHandle): else: base = ir.PointerType(base) target_type = base - elif isinstance(type_arg, ast.Attribute): - if isinstance(type_arg.value, ast.Name) and IsTModule(type_arg.value.id, self.Trans.SymbolTable): - attr_name: str = type_arg.attr - ctype_cls: type | None = CTypeRegistry.GetClassByName(attr_name) - if ctype_cls is not None: - llvm_str: str | None = CTypeRegistry.CTypeToLLVM(ctype_cls) - resolved: ir.Type | None = Gen._type_str_to_llvm(llvm_str) - if resolved: - target_type = resolved - # 常规分支未命中:走注解解析同一规则源(typedef / `T*` 指针后缀 / t.* 组合写法)。 + # 常规分支未命中:走注解解析同一规则源(typedef / `T*` 指针后缀 / 联合类型组合写法)。 # 该规则源对未收录的名字会退化成 `%"{mod}.名"*` 假结构体(CStruct),故显式判掉。 if target_type is None: type_info: CTypeInfo | None = CTypeInfo.FromNode(type_arg, self.Trans.SymbolTable) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 3ef2fa3..eaff46f 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -10,10 +10,10 @@ import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode -from lib.includes import t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry from lib.core.SymbolUtils import ( - IsTModule, ExtractTypeNameFromBinOp, IsPtrSubscriptNode, DesugarPtrSubscriptToUnion, + ExtractTypeNameFromBinOp, IsPtrSubscriptNode, DesugarPtrSubscriptToUnion, ResolveTypeArgStr, GenericArgRawName, ClassHasFuncLevelCVTable, IsVtableSlotMethod) from lib.core.Handles.HandlesExpr import DefineUseWidthFromLLVMType @@ -23,20 +23,11 @@ from lib.vast.ExprParser import NEW_SRC_MEMGR # len() 参数形态不支持时的共享提示语(与 ViperC App/lib/core/Gen/Call/ # CallGenDispatch.vp 的 len() 分支同口径,措辞逐字一致,便于用户对照两侧报文)。 _LEN_SUPPORTED_HINT: str = ( - "len() 只支持定长数组/数组指针(t.CArray[T, N])、i8*(str/bytes)或带 __len__ 的结构体;" + "len() 只支持定长数组/数组指针(CArray[T, N])、i8*(str/bytes)或带 __len__ 的结构体;" "非 i8 裸指针/标量指针没有长度语义:字符串请用 str/bytes,需要元素个数请自行记录长度," - "或改用 t.CPtr[元素] 并显式维护元素计数" + "或改用 CPtr[元素] 并显式维护元素计数" ) -# 已删除的用户可见 CIf 族(c.CIf / c.CIfdef / c.CIfndef / c.CElif / c.CElse / c.CEndif): -# 用户再写即在调用点 FailFast,指向原生 cif/celif/celse 与 defined(NAME)(英文报文, -# 与 ViperC CallGenDispatch.vp 同口径)。内部标记 c.@CIf 族不受影响。 -_REMOVED_CIF_CALL_MSG: str = ( - "c.CIf / c.CIfdef / c.CIfndef / c.CElif / c.CElse / c.CEndif were removed; use the cif / " - "celif / celse statements together with the defined(NAME) predicate instead " - "(e.g. `cif defined(NAME):` ... `celif ...:` ... `celse:` ...)") - - # PROF 热点:_EmitLLVMIRInstruction 对每条 IR 模板都要做多次 re.match / re.split, # 未预编译的模块级入口每次都要「模式串哈希 → re 缓存查找 → 未命中就重新编译」, # 512 条缓存被打穿后开销巨大。这些模式全是字面量 → 提升为模块级预编译常量。 @@ -83,9 +74,9 @@ def _safe_ptr_type(ty: ir.Type) -> ir.Type: def _BinOpContainsCPtr(node: ast.AST) -> bool: - """递归检查 BinOp(BitOr) 联合类型中是否含 t.CPtr(指针标记)""" - if isinstance(node, ast.Attribute): - return node.attr == 'CPtr' + """递归检查 BinOp(BitOr) 联合类型中是否含 CPtr(指针标记)""" + if isinstance(node, ast.Name): + return node.id == 'CPtr' if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): return _BinOpContainsCPtr(node.left) or _BinOpContainsCPtr(node.right) return False @@ -338,7 +329,7 @@ class ExprCallHandle(BaseHandle): def _ConstantToIrValue(raw: object, param_type: ir.Type, Gen: LlvmGeneratorMixin) -> ir.Value | None: """把全局默认参数表里的 Python 常量转成形参类型的 IR 常量。 - 只处理整数/布尔(跨模块默认值里最常见,如 cap: t.CSizeT = 4096)。字符串等 + 只处理整数/布尔(跨模块默认值里最常见,如 cap: CSizeT = 4096)。字符串等 常量需要在调用点引用定义模块的全局对象,无法安全重建 → 返回 None,调用点 退回原有零值填充(与修复前行为一致)。 """ @@ -398,7 +389,7 @@ class ExprCallHandle(BaseHandle): """函数指针间接调用前的 arity 校验(fail-fast,紧邻 builder.call 之前)。 期望形参个数取自 FnPtr 的静态 LLVM 函数类型的形参表:来源是函数指针槽 - (模块级/局部 t.Callable[...] 注解)的 CTypeInfo.FuncPtrParams → + (模块级/局部 Callable[...] 注解)的 CTypeInfo.FuncPtrParams → CTypeInfo.ToLLVM/_ctype_to_llvm → ir.FunctionType(ret, params);变参位由 FunctionType.var_arg 承载。不校验时,实参个数少于形参个数会让 llvmlite CallInstr 按形参个数索引 args[i] 抛裸 `IndexError: list index out of range` @@ -440,7 +431,7 @@ class ExprCallHandle(BaseHandle): if IsVariadic else f" {Expected} 个形参") raise Exception( f"[TransPyC] 函数指针调用实参个数不匹配: '{FuncName}' 期望{ExpectText}," - f"实际传入 {Actual} 个实参;请检查该函数指针(t.Callable[...] 注解槽)的" + f"实际传入 {Actual} 个实参;请检查该函数指针(Callable[...] 注解槽)的" f"形参表是否与调用处实参个数一致。位置 {Loc}" f"{(',源码: ' + SourceLine) if SourceLine else ''}" ) @@ -531,15 +522,50 @@ class ExprCallHandle(BaseHandle): ModulePath: str | None = None if isinstance(Node.func, ast.Name): FuncName = Node.func.id - # __asm__(...) 语法糖:等价 c.Asm(...)(裸名调用,无需 import c) + # __asm__(...) 语法糖:等价 Asm(...)(裸名调用,无需 import c) if FuncName == '__asm__': return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node) - # __llvmir__(...) 语法糖:等价 c.LLVMIR(...) + # __llvmir__(...) 语法糖:等价 LLVMIR(...) if FuncName == '__llvmir__': return self._HandleLLVMIRLlvm(Node) - # irinp/irout 等价 c.LInp/c.LOut(仅作模板占位符,独立调用返回 0) + # irinp/irout 等价 LInp/LOut(仅作模板占位符,独立调用返回 0) if FuncName in ('irinp', 'irout'): return ir.Constant(ir.IntType(32), 0) + # 内建语法糖调用(裸名):Asm / Addr / Deref / DerefAs / Set / Load / + # PtrToInt / CError / AsmInp / AsmOut / LLVMIR / LInp / LOut / + # CPragma / CUndef 不是普通函数,优先于符号查找。 + if FuncName == 'Asm': + return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node) + if FuncName == 'Addr': + return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node) + if FuncName == 'Set': + return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node) + if FuncName == 'Load': + return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node) + if FuncName == 'Deref': + return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node) + if FuncName == 'DerefAs': + return self._HandleCDerefAsLlvm(Node) + if FuncName == 'PtrToInt': + return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node) + if FuncName in ('AsmInp', 'AsmOut', 'LInp', 'LOut'): + return ir.Constant(ir.IntType(32), 0) + if FuncName == 'LLVMIR': + return self._HandleLLVMIRLlvm(Node) + if FuncName in ('CPragma', 'CUndef'): + return ir.Constant(ir.IntType(1), 1) + if FuncName == 'CError': + msg = "compile-time error" + if Node.args: + arg = Node.args[0] + if isinstance(arg, ast.Constant) and isinstance(arg.value, str): + msg = arg.value + lineno = getattr(Node, 'lineno', 0) + # 注入行偏移还原:AST 行号含 _inject_auto_imports 注入的 N 行 + _line_offset: int = int(getattr(self.Trans, '_line_offset', 0) or 0) + if _line_offset > 0 and lineno > _line_offset: + lineno -= _line_offset + raise Exception(f"#error: {msg} (line {lineno})") # M1 协程:普通函数调用 async 函数 → create_()(返回帧指针) if hasattr(self.Trans, 'AsyncHandler') and self.Trans.AsyncHandler._IsAsyncFunc(FuncName): return self.Trans.AsyncHandler._HandleAsyncCreateCallLlvm(Node, FuncName) @@ -588,12 +614,12 @@ class ExprCallHandle(BaseHandle): ClassName = Gen.var_struct_class.get(FuncName) if ClassName and Gen._has_function(f'{ClassName}.__call__'): return self._HandleInstanceCallLlvm(Node, FuncName, ClassName) - t_c_imported = getattr(self.Trans, '_t_c_imported_names', {}) + t_c_imported = getattr(self.Trans, '_from_import_aliases', {}) if FuncName in t_c_imported: src_module, src_name = t_c_imported[FuncName] virtual_node = self._make_virtual_attr_call(Node, src_module, src_name) return self._HandleCallLlvm(virtual_node) - # 检查是否是全局变量中的函数指针(t.Callable 类型在模块级定义) + # 检查是否是全局变量中的函数指针(Callable 类型在模块级定义) if FuncName not in Gen.variables and FuncName in Gen.global_vars: Gen._Load_var(FuncName) if FuncName not in Gen.variables and FuncName in Gen.module.globals: @@ -605,7 +631,7 @@ class ExprCallHandle(BaseHandle): # 检查是否是闭包变量(lambda 赋值给变量后调用) if FuncName in Gen.variables and Gen.variables[FuncName] is not None: VarPtr = Gen.variables[FuncName] - # 检查是否是函数指针变量(t.Callable 类型),直接加载并调用 + # 检查是否是函数指针变量(Callable 类型),直接加载并调用 if isinstance(VarPtr, ir.GlobalVariable) and isinstance(VarPtr.type, ir.PointerType) and isinstance(VarPtr.type.pointee, ir.PointerType) and isinstance(VarPtr.type.pointee.pointee, ir.FunctionType): fn_ptr = Gen._load(VarPtr, name=f"Load_fn_{FuncName}") args = [] @@ -625,8 +651,8 @@ class ExprCallHandle(BaseHandle): args.append(ArgVal) self._CheckFuncPtrArity(Node, fn_ptr, args, FuncName, Gen) return Gen.builder.call(fn_ptr, args, name=f"call_{FuncName}") - # 处理 t.CPtr (i8*) 函数指针调用 - # 当函数被赋值给 t.CPtr 变量时,原始函数类型退化为 i8* + # 处理 CPtr (i8*) 函数指针调用 + # 当函数被赋值给 CPtr 变量时,原始函数类型退化为 i8* # 检查是否是闭包变量(通过 _closure_var_types 追踪) if isinstance(closure_ptr.type, ir.PointerType) and isinstance(closure_ptr.type.pointee, ir.IntType) and closure_ptr.type.pointee.width == 8: ClosureInfo: tuple[ir.Type, list[ir.Type]] | None = Gen._closure_var_types.get(FuncName) @@ -700,10 +726,10 @@ class ExprCallHandle(BaseHandle): # TypeGenResolve.vp:921)。落到下方 typedef 表判据必然 miss ⇒ 误报 # "Undefined function: 'rawptr'"(ViperC/App/lib/core/Gen/ # StructGenMixin.vp `vt_ptr: rawptr = rawptr(*(uint64*)(default_val))` 根因)。 - # 单独 rawptr 等价 t.CPtr(void* → i8*):目标类型取内置 rawptr 的权威 + # 单独 rawptr 等价 CPtr(void* → i8*):目标类型取内置 rawptr 的权威 # CTypeInfo(_builtin_rawptr_info,与注解侧同源),转换复用 (rawptr[X])(x) - # / (t.CPtr)(x) 的 _emit_rawptr_cast——不新造第二套 rawptr 表示。 - # 不照抄 uchar 的做法(往 builtins.vp 加 `uchar: t.CTypedef = ...`): + # / (CPtr)(x) 的 _emit_rawptr_cast——不新造第二套 rawptr 表示。 + # 不照抄 uchar 的做法(往 builtins.vp 加 `uchar: CTypedef = ...`): # rawptr 不是普通 typedef 名而是内置语法,VPC register_ctypedef 显式拒绝 # 重定义(TypeGenCType.vp:157-160)、TPC builtins_typedef_value 亦硬编码 # 返回内置值(TypeAnnotationResolver.py:313-314)⇒ 该声明不生效。 @@ -715,7 +741,7 @@ class ExprCallHandle(BaseHandle): return self._emit_rawptr_cast(Node, Gen, _rawptr_target) # builtins 隐式 CTypedef 作为类型转换调用(uint64(x)/int64(x)/size_t(x) 等, # builtins.vp 声明、无需 import,不注册进 SymbolTable):常规 miss 后在此 - # 尝试 typedef cast(uint64(buf) = t.CUInt64T(buf)),否则报 + # 尝试 typedef cast(uint64(buf) = CUInt64T(buf)),否则报 # "Undefined function: 'uint64'"(includes/ast/base.vp bootstrap 根因)。 _td_diag: str = '' try: @@ -729,18 +755,18 @@ class ExprCallHandle(BaseHandle): if FuncName in _td_table: # from_type_name 对裸 typedef 名(uint64 等)解析不出真实类型类 # (BuiltinTypeMap 无此键,CreateFromTypeName 落空成空 CType), - # 因此改走权威 typedef 值:'t.CUInt64T' → CTypeRegistry.NameToLLVM + # 因此改走权威 typedef 值:'CUInt64T' → CTypeRegistry.NameToLLVM # → 'i64'(与 DeclarationGenerator 的 stub 兜底同机制)。 _bv_td: str | None = _TAR_TD.builtins_typedef_value(FuncName) _lls_td: str | None = None if _bv_td: - _nm_td: str = _bv_td[2:] if _bv_td.startswith('t.') else _bv_td - from lib.includes.t import CTypeRegistry as _CR_TD + _nm_td: str = _bv_td + from lib.core.TypeSystem import CTypeRegistry as _CR_TD _lls_td = _CR_TD.NameToLLVM(_nm_td) if not _lls_td: # 声明值本身也是短别名(新语法:`typedef short = int16`、 # `typedef longlong = int64`)⇒ 单步 NameToLLVM(不认短别名) - # 落空。改走权威链式解析(builtins.vp 声明 → 逐级展开到 t.C*), + # 落空。改走权威链式解析(builtins.vp 声明 → 逐级展开到 C* 类型), # 与注解位置 LLVMTypeMapper._resolve_name 同一来源。 _td_info = _TAR_TD._lookup_builtins_typedef(FuncName, self.Trans.SymbolTable) if _td_info is not None and _td_info.BaseType: @@ -749,9 +775,7 @@ class ExprCallHandle(BaseHandle): if len(Node.args) >= 2: _p2b: ast.AST = Node.args[1] _p2b_cptr: bool = ( - (isinstance(_p2b, ast.Attribute) and _p2b.attr == 'CPtr' - and isinstance(_p2b.value, ast.Name) and _p2b.value.id in ('t', 'c')) or - (isinstance(_p2b, ast.Name) and _p2b.id == 'CPtr') + isinstance(_p2b, ast.Name) and _p2b.id == 'CPtr' ) if _p2b_cptr: if isinstance(_tg_td2, ir.PointerType): @@ -761,18 +785,16 @@ class ExprCallHandle(BaseHandle): if _lls_td: _tg_td: ir.Type = Gen._ctype_to_llvm(_lls_td) if isinstance(_tg_td, (ir.IntType, ir.FloatType, ir.DoubleType, ir.PointerType)): - # 双参数形式 uint8(s, t.CPtr) / int64(v, CPtr):第二参是 - # CPtr 标记 → 指针包装(等价旧写法 t.CUInt8T(s, t.CPtr), - # 对齐 Attribute 形式 t.CXXX(v, t.CPtr) 的 IsPtr_cast 语义)。 + # 双参数形式 uint8(s, CPtr) / int64(v, CPtr):第二参是 + # CPtr 标记 → 指针包装(等价旧写法 CUInt8T(s, CPtr), + # 对齐 CXXX(v, CPtr) 的 IsPtr_cast 语义)。 # 单参形式 uint64(buf) 才是标量转换。忽略第二参会把 # hashlib/__sha1.vp 的 data 编译成标量 → 运行时 sha1 # transform 读越界崩溃。 if len(Node.args) >= 2: _p2_td: ast.AST = Node.args[1] _p2_cptr: bool = ( - (isinstance(_p2_td, ast.Attribute) and _p2_td.attr == 'CPtr' - and isinstance(_p2_td.value, ast.Name) and _p2_td.value.id in ('t', 'c')) or - (isinstance(_p2_td, ast.Name) and _p2_td.id == 'CPtr') + isinstance(_p2_td, ast.Name) and _p2_td.id == 'CPtr' ) if _p2_cptr: if isinstance(_tg_td, ir.PointerType): @@ -789,15 +811,13 @@ class ExprCallHandle(BaseHandle): # Handle list[int](mb) syntax — generic class constructor with explicit type args # Handle xxx[T](x) syntax — generic function call with explicit type args sub: ast.Subscript = Node.func - # (rawptr[X])(expr) / (t.CPtr[X])(expr):内建裸指针转换(无泛型模板)。 + # (rawptr[X])(expr) / (CPtr[X])(expr):内建裸指针转换(无泛型模板)。 # 不拦截 → 泛型模板查不到 → 落 L850 "Unsupported call expression" # (StubMergerCollect.vp L271 bootstrap 根因)。 _sub_nm: str | None = None if isinstance(sub.value, ast.Name): _sub_nm = sub.value.id - elif isinstance(sub.value, ast.Attribute) and isinstance(sub.value.value, ast.Name) and sub.value.value.id == 't' and sub.value.attr == 'CPtr': - _sub_nm = 't.CPtr' - if _sub_nm in ('rawptr', 't.CPtr'): + if _sub_nm in ('rawptr', 'CPtr'): return self._HandleSubscriptPtrCastLlvm(Node, sub) if isinstance(sub.value, ast.Name): FuncName: str = sub.value.id @@ -815,13 +835,13 @@ class ExprCallHandle(BaseHandle): spec_name = self._ResolveGenericSlice(Node.func.value) if spec_name: return self._HandleSizeofLlvm(ast.Name(id=spec_name, ctx=ast.Load())) - # 对于 BinOp/BitOr 联合类型(如 AST | t.CPtr), + # 对于 BinOp/BitOr 联合类型(如 AST | CPtr), # sizeof 应返回指针大小 8,而非结构体大小 # 必须在 HandleExprLlvm 之前检查,避免对类型名求值产生副作用 if isinstance(Node.func.value, ast.BinOp) and isinstance(Node.func.value.op, ast.BitOr): if self._AnnotationContainsCPtr(Node.func.value): return ir.Constant(ir.IntType(64), 8) - # 对于 ast.Attribute(如 ast.ClassDef.__sizeof__() / t.CInt.__sizeof__()), + # 对于 ast.Attribute(如 ast.ClassDef.__sizeof__() / CInt.__sizeof__()), # 直接调用 _HandleSizeofLlvm,不走 HandleExprLlvm # 因为 ast.Attribute 在 sizeof 上下文中一定是类型名,不是变量 if isinstance(Node.func.value, ast.Attribute): @@ -879,7 +899,7 @@ class ExprCallHandle(BaseHandle): # 统一获取模块 SHA1,用于跨模块类型引用(确保用源模块的 SHA1 而非当前模块) # 放在 ModulePath 和 alias 解析之后,供所有 _HandleClassNewLlvm/_ensure_struct_declared 调用点使用 _ctor_module_sha1: str | None = None - if ModulePath and ModulePath not in {'t', 'c'}: + if ModulePath: _ctor_sha1_map: dict[str, str] = getattr(Gen, 'ModuleSha1Map', {}) _ctor_module_sha1 = _ctor_sha1_map.get(ModulePath) if not _ctor_module_sha1 and '.' in ModulePath: @@ -927,50 +947,14 @@ class ExprCallHandle(BaseHandle): if (is_instance_var or _is_chained_instance) and not is_class_name: return self._HandleMethodCallLlvm(Node) FuncAttr = Node.func.attr - # c 模块的特殊语法设施(Addr/Deref/DerefAs/Set/Load/Asm 等)必须优先处理, - # 即使它们在 Gen.structs 中(c.py 的类会被声明为结构体但不应被实例化)。 - # c.py 是语法部分,不应被编译,其中的类是编译器语法设施。 - # 必须在 Gen.structs 检查之前处理,否则 c.Deref/c.DerefAs 会被 - # _HandleClassNewLlvm 当成普通类实例化(根因:HandlesExprCall.py:497)。 - if ModulePath == 'c': - if FuncAttr == 'Asm': - return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node) - elif FuncAttr == 'Addr': - return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node) - elif FuncAttr == 'Set': - return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node) - elif FuncAttr == 'Load': - return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node) - elif FuncAttr == 'Deref': - return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node) - elif FuncAttr == 'DerefAs': - return self._HandleCDerefAsLlvm(Node) - elif FuncAttr == 'PtrToInt': - return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node) - elif FuncAttr in ('CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif'): - from lib.core.LLVMCG.FuncGen import FailFastError - raise FailFastError(_REMOVED_CIF_CALL_MSG) - elif FuncAttr == 'CError': - msg = "compile-time error" - if Node.args: - arg = Node.args[0] - if isinstance(arg, ast.Constant) and isinstance(arg.value, str): - msg = arg.value - lineno = getattr(Node, 'lineno', 0) - # 注入行偏移还原:AST 行号含 _inject_auto_imports 注入的 N 行 - _line_offset: int = int(getattr(self.Trans, '_line_offset', 0) or 0) - if _line_offset > 0 and lineno > _line_offset: - lineno -= _line_offset - raise Exception(f"#error: {msg} (line {lineno})") - elif FuncAttr in ('AsmInp', 'AsmOut'): - return ir.Constant(ir.IntType(32), 0) - elif FuncAttr == 'LLVMIR': - return self._HandleLLVMIRLlvm(Node) - elif FuncAttr in ('LInp', 'LOut'): - return ir.Constant(ir.IntType(32), 0) + # 语法糖调用一律使用裸内建名;t./c. 前缀在调用点直接报错。 + if ModulePath in ('t', 'c'): + raise TypeError( + f"[TPC] 类型注解/调用不再接受 '{ModulePath}.' 前缀;" + f"请直接写裸内建名,如 {FuncAttr}(...)") # stdarg 模块的变参糖:stdarg.arg / stdarg.va_arg / stdarg.va_start / # stdarg.va_end 命中与裸名同名内建**完全相同**的处理(stdarg 是编译器 - # 拦截的糖模块,不是真符号,与 c 模块的语法设施同一口径)。仅当 + # 拦截的糖模块,不是真符号,与内建语法糖同一口径)。仅当 # ModulePath 恰为 'stdarg' 时进入,不会抢掉其它模块/用户模块的调用。 if ModulePath == 'stdarg': if FuncAttr == 'arg': @@ -1101,11 +1085,6 @@ class ExprCallHandle(BaseHandle): result = self._HandleClassNewLlvm(Node, FuncAttr, module_sha1=_ctor_module_sha1) if result is not None: return result - if ModulePath == 't': - MethodResult_t = self._HandleMethodCallLlvm(Node) - if MethodResult_t is not None: - return MethodResult_t - raise Exception(f"Undefined method: 't.{FuncAttr}'") if isinstance(Node.func.value, ast.Attribute): inner_attr = Node.func.value.attr if inner_attr in Gen.structs or self.Trans.SymbolTable.is_struct(inner_attr): @@ -1122,7 +1101,7 @@ class ExprCallHandle(BaseHandle): MethodResult = self._HandleMethodCallLlvm(Node) IsZeroResult = isinstance(MethodResult, ir.Constant) and isinstance(MethodResult.type, ir.IntType) and MethodResult.constant == 0 if IsZeroResult and FuncAttr is not None: - mangled_name = Gen._mangle_func_name(FuncAttr, ModulePath if ModulePath and ModulePath != 't' else None) + mangled_name = Gen._mangle_func_name(FuncAttr, ModulePath if ModulePath else None) if Gen._has_function(mangled_name): CallArgs = [] for ArgIdx, arg in enumerate(Node.args, start=1): @@ -1141,7 +1120,7 @@ class ExprCallHandle(BaseHandle): IsKnown = (LastPart in imported or LastPart in self.Trans.SymbolTable.import_aliases or LastPart in ModuleSha1Map) # 最后尝试: 用 FuncAttr 直接查找 Gen.functions(_find_function 会遍历 SHA1 前缀) - if FuncAttr and ModulePath and ModulePath not in {'t', 'c'}: + if FuncAttr and ModulePath: # _ctor_module_sha1 已在函数顶部统一获取,此处无需重复 # 先检查 FuncAttr 是否是函数/变量,如果是则跳过 struct 声明 _attr_sym = self.Trans.SymbolTable.lookup(FuncAttr) @@ -1206,7 +1185,7 @@ class ExprCallHandle(BaseHandle): return self._check_eh_return(result, FuncAttr, Gen, called_func=func_decl) if ModulePath and IsKnown: raise Exception(f"Undefined symbol: '{ModulePath}.{FuncAttr}'") - if ModulePath and ModulePath not in {'t', 'c'} and not IsKnown: + if ModulePath and not IsKnown: raise Exception(f"Unknown module: '{ModulePath}' (undefined symbol: '{ModulePath}.{FuncAttr}')") if not ModulePath and FuncAttr: raise Exception(f"Undefined method: '{FuncAttr}'") @@ -1550,10 +1529,8 @@ class ExprCallHandle(BaseHandle): parts.append(value.value) elif isinstance(value, ast.FormattedValue): expr = value.value - # c.LInp/c.LOut 与裸名 irinp/irout 等价(见 _intrinsic_marker) + # LInp/LOut 与裸名 irinp/irout 等价(见 _intrinsic_marker) _marker: str | None = self.Trans.ExprAsmHandle._intrinsic_marker(expr) - _is_c_qualified: bool = (isinstance(expr, ast.Call) and isinstance(expr.func, ast.Attribute) - and isinstance(expr.func.value, ast.Name) and expr.func.value.id == 'c') if _marker == 'LInp': if expr.args: val = self.HandleExprLlvm(expr.args[0]) @@ -1574,8 +1551,8 @@ class ExprCallHandle(BaseHandle): all_ops.append(('out', len(output_targets) - 1)) parts.append(f'%__OP{operand_seq}__') operand_seq += 1 - elif not _is_c_qualified: - # c.* 中非 LInp/LOut 的形态不收集(保持原行为) + else: + # 非标记表达式按普通输入操作数处理 fallback = self.HandleExprLlvm(expr) if fallback: input_ops.append(fallback) @@ -1902,14 +1879,14 @@ class ExprCallHandle(BaseHandle): Gen = self.Trans.LlvmGen # 解析 import 别名: 如 window -> vpsdk.window - if ModulePath and ModulePath not in ('c', 't'): + if ModulePath: ModulePath = self.Trans.SymbolTable.resolve_alias(ModulePath) - is_user_module = (ModulePath and ModulePath not in ('c', 't') and + is_user_module = (ModulePath and (ModulePath in Gen.ModuleSha1Map or ModulePath in getattr(self.Trans, '_ImportedModules', set()) or ModulePath in self.Trans.SymbolTable.import_aliases)) - if ModulePath and ModulePath not in ('c', 't') and not is_user_module: + if ModulePath and not is_user_module: is_user_module = (ModulePath in Gen.ModuleSha1Map or ModulePath.split('.')[-1] in Gen.ModuleSha1Map or ModulePath.split('.')[-1] in getattr(self.Trans, '_ImportedModules', set())) @@ -1922,7 +1899,7 @@ class ExprCallHandle(BaseHandle): # 插入了 IsModuleAlias 的 AliasInfo,据此识别并补全完整路径,使 # `X.get_perm_pool()` 正确解析为模块函数({sha1}.get_perm_pool)而非 # 类方法({sha1}.X.get_perm_pool,链接 undefined symbol)。 - if ModulePath and ModulePath not in ('c', 't') and not is_user_module: + if ModulePath and not is_user_module: _al_last = ModulePath.split('.')[-1] _al_sym = self.Trans.SymbolTable.lookup(_al_last) if _al_sym and getattr(_al_sym, 'IsModuleAlias', False): @@ -1934,7 +1911,7 @@ class ExprCallHandle(BaseHandle): if is_user_module: mangled_name = Gen._mangle_func_name(func_name, ModulePath) sym_info = self.LookupFunctionSymbol(func_name, module_path=ModulePath) - is_inline = sym_info and (sym_info.IsInline or isinstance(sym_info.Storage, t.CInline)) + is_inline = sym_info and (sym_info.IsInline or isinstance(sym_info.Storage, TypeSystem.CInline)) if is_inline and sym_info.InlineBody: self._HandleInlineExpandLlvm(Node, sym_info) return ir.Constant(ir.IntType(32), 1) @@ -2015,43 +1992,6 @@ class ExprCallHandle(BaseHandle): return self._HandleClosureCallLlvm(Node, func_name) return None - if ModulePath == 'c': - if func_name == 'Asm': - return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node) - elif func_name == 'Addr': - return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node) - elif func_name == 'Set': - return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node) - elif func_name == 'Load': - return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node) - elif func_name == 'Deref': - return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node) - elif func_name == 'DerefAs': - return self._HandleCDerefAsLlvm(Node) - elif func_name == 'PtrToInt': - return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node) - elif func_name in ('CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif'): - from lib.core.LLVMCG.FuncGen import FailFastError - raise FailFastError(_REMOVED_CIF_CALL_MSG) - elif func_name == 'CError': - msg = "compile-time error" - if Node.args: - arg = Node.args[0] - if isinstance(arg, ast.Constant) and isinstance(arg.value, str): - msg = arg.value - lineno = getattr(Node, 'lineno', 0) - # 注入行偏移还原:AST 行号含 _inject_auto_imports 注入的 N 行 - _line_offset: int = int(getattr(self.Trans, '_line_offset', 0) or 0) - if _line_offset > 0 and lineno > _line_offset: - lineno -= _line_offset - raise Exception(f"#error: {msg} (line {lineno})") - elif func_name in ('AsmInp', 'AsmOut'): - return ir.Constant(ir.IntType(32), 0) - elif func_name == 'LLVMIR': - return self._HandleLLVMIRLlvm(Node) - elif func_name in ('LInp', 'LOut'): - return ir.Constant(ir.IntType(32), 0) - win32_apis = { 'SetConsoleOutputCP': (ir.IntType(32), [ir.IntType(32)]), 'SetConsoleCP': (ir.IntType(32), [ir.IntType(32)]), @@ -2148,13 +2088,13 @@ class ExprCallHandle(BaseHandle): if target_type_str and type_info.IsPtr and not IsPtr: if '*' not in target_type_str: target_type_str += ' *' - if isinstance(type_info.Storage, t.CExport) or isinstance(type_info.Storage, t.CExtern): + if isinstance(type_info.Storage, TypeSystem.CExport) or isinstance(type_info.Storage, TypeSystem.CExtern): pass if type_info.IsState: Gen._export_funcs.add('_type_union_cast') else: # Fallback 路径:MergeTypes 失败(返回 None 或抛异常)时,手动从 BinOp 提取类型信息 - # 处理 (BaseType | t.CPtr) 这种模式,手动解析为 "{BaseType} *" + # 处理 (BaseType | CPtr) 这种模式,手动解析为 "{BaseType} *" _vlog().warning( f"_HandleTypeUnionCastLlvm: MergeTypes 未返回 CTypeInfo " f"(type_info={type_info!r}, exception={MergeException!r}),启用 fallback 手动解析" @@ -2162,8 +2102,8 @@ class ExprCallHandle(BaseHandle): target_type_str = self._ExtractTypeStrFromUnionBinOp(Node.func) if not target_type_str: # fail-fast(原为 _vlog().warning + return None): - # `(T | t.CPtr)(x)` 只可能来自指针强转——parser 把 `(T*)x` / `(T*)(x)` / - # `T*(x)`(含 `**`)统一产成 func = `T | t.CPtr` 的 Call(见 + # `(T | CPtr)(x)` 只可能来自指针强转——parser 把 `(T*)x` / `(T*)(x)` / + # `T*(x)`(含 `**`)统一产成 func = `T | CPtr` 的 Call(见 # vast/ExprParser._ConsumePtrSuffixCall、vast_c.c ConsumePtrSuffixCall)。 # 该形态必须有值产出;返回 None 会让调用方把整条表达式当"编译期求值为空" # 丢掉(现场:ViperC ExprGenBase.vp:360 `v = (ast.Expr*(node)).value` @@ -2246,12 +2186,12 @@ class ExprCallHandle(BaseHandle): def _ExtractTypeStrFromUnionBinOp(self, NodeFunc: ast.AST) -> str | None: """Fallback:从类型联合 BinOp 手动提取类型字符串。 - 处理 (BaseType | t.CPtr) 这种模式,手动解析为 "{BaseType} *"。 - 支持嵌套的 | 操作(如 (t.CInt | t.CPtr) | t.CStatic)。 + 处理 (BaseType | CPtr) 这种模式,手动解析为 "{BaseType} *"。 + 支持嵌套的 | 操作(如 (CInt | CPtr) | CStatic)。 策略: - 递归展平所有 | 操作数 - - t.CPtr 视为指针修饰符(生成 "{BaseType} *" 格式) + - CPtr 视为指针修饰符(生成 "{BaseType} *" 格式) - 其他 CType 子类作为基础类型(取第一个) - 跳过存储类/限定符修饰符(CExport/CExtern/CStatic/CConst/CVolatile/CInline 等) """ @@ -2279,7 +2219,7 @@ class ExprCallHandle(BaseHandle): CollectOperands(NodeFunc) - HasCPtr = False # 是否包含 t.CPtr(指针修饰符) + HasCPtr = False # 是否包含 CPtr(指针修饰符) BaseTypeName = None # 基础类型名(如 "CInt"、"CChar") for Operand in Operands: @@ -2291,7 +2231,7 @@ class ExprCallHandle(BaseHandle): else: continue - # t.CPtr 是指针修饰符,单独处理(增加一层 *) + # CPtr 是指针修饰符,单独处理(增加一层 *) if AttrName == 'CPtr': HasCPtr = True continue @@ -2300,9 +2240,9 @@ class ExprCallHandle(BaseHandle): if AttrName in StorageQualifierNames: continue - # 通过 t 模块获取类型类,验证是否为 CType 子类 - TypeClass = getattr(t, AttrName, None) - if not (isinstance(TypeClass, type) and issubclass(TypeClass, t.CType)): + # 通过 TypeSystem 获取类型类,验证是否为 CType 子类 + TypeClass = getattr(TypeSystem, AttrName, None) + if not (isinstance(TypeClass, type) and issubclass(TypeClass, TypeSystem.CType)): # 非 CType 类,跳过 continue @@ -2313,7 +2253,7 @@ class ExprCallHandle(BaseHandle): if not BaseTypeName: return None - # 包含 t.CPtr 时,生成 "{BaseType} *" 格式 + # 包含 CPtr 时,生成 "{BaseType} *" 格式 # _CType2LLVM 已验证能解析 "CInt *" → i32*(ir.PointerType(ir.IntType(32))) if HasCPtr: return f"{BaseTypeName} *" @@ -2499,11 +2439,11 @@ class ExprCallHandle(BaseHandle): return ArgVal def _HandleSubscriptPtrCastLlvm(self, Node: ast.Call, sub: ast.Subscript) -> ir.Value: - """(rawptr[X])(expr) / (t.CPtr[X])(expr) 内建指针转换:expr → X* + """(rawptr[X])(expr) / (CPtr[X])(expr) 内建指针转换:expr → X* rawptr 是编译器内建裸指针语法(无 SymbolTable typedef 条目、无泛型模板), 此前 Subscript 调用仅查泛型模板 → 落空后报 "Unsupported call expression" - (StubMergerCollect.vp `(rawptr[FileEntry])(t.CVoid(...))` bootstrap 根因)。 + (StubMergerCollect.vp `(rawptr[FileEntry])(CVoid(...))` bootstrap 根因)。 目标类型经 TypeMergeHandler.GetCTypeInfo 解析 Subscript 类型节点获得。 """ Gen: LlvmGeneratorMixin = self.Trans.LlvmGen @@ -2819,14 +2759,10 @@ class ExprCallHandle(BaseHandle): @staticmethod def _has_cvtable_decorator(node: ast.ClassDef) -> bool: - """检查 ClassDef 是否有 @t.CVTable 装饰器(或 @CVTable)""" + """检查 ClassDef 是否有 @CVTable 装饰器(或 @CVTable)""" for decorator in node.decorator_list: - if isinstance(decorator, ast.Attribute) and getattr(decorator.value, 'id', None) == 't' and decorator.attr == 'CVTable': - return True if isinstance(decorator, ast.Call): inner = decorator.func - if isinstance(inner, ast.Attribute) and getattr(inner.value, 'id', None) == 't' and inner.attr == 'CVTable': - return True if isinstance(inner, ast.Name) and inner.id == 'CVTable': return True if isinstance(decorator, ast.Name) and decorator.id == 'CVTable': @@ -2835,16 +2771,14 @@ class ExprCallHandle(BaseHandle): @staticmethod def _has_novtable_decorator(node: ast.ClassDef) -> bool: - """检查 ClassDef 是否有 @t.NoVTable 装饰器""" + """检查 ClassDef 是否有 @NoVTable 装饰器""" for decorator in node.decorator_list: - if isinstance(decorator, ast.Attribute) and getattr(decorator.value, 'id', None) == 't' and decorator.attr == 'NoVTable': - return True if isinstance(decorator, ast.Name) and decorator.id == 'NoVTable': return True return False def _try_register_vtable_ondemand(self, ClassName: str, class_sha1: str, Gen: "LlvmGeneratorMixin") -> None: - """按需 vtable 注册:从 .pyi stub 检查 @t.CVTable 并注册到 vtable 集合。 + """按需 vtable 注册:从 .pyi stub 检查 @CVTable 并注册到 vtable 集合。 沿继承链递归收集方法,保证 vtable 布局与 prescan 的 _EmitClassLlvm 一致: - 基类方法在前(固定索引,保证多态分派正确) @@ -2852,9 +2786,9 @@ class ExprCallHandle(BaseHandle): - 子类覆盖的方法放在父类的位置(用子类实现) 与 prescan 的 _resolve_class_flags 逻辑一致: - - 类自身有 @t.CVTable → 注册 - - 类自身有 @t.NoVTable → 不注册 - - 类继承 @t.CVTable 基类(且无 @t.NoVTable)→ 注册(自动启用 CVTable) + - 类自身有 @CVTable → 注册 + - 类自身有 @NoVTable → 不注册 + - 类继承 @CVTable 基类(且无 @NoVTable)→ 注册(自动启用 CVTable) """ try: import_handler = self.Trans.ImportHandler @@ -2976,7 +2910,7 @@ class ExprCallHandle(BaseHandle): pass # 父类是 NoVTable,不继承 vtable # 继承链统一 vtable(与 _resolve_class_flags 一致): - # 类自身无 @t.CVTable 时,第一个父类有 vtable → 子类启用; + # 类自身无 @CVTable 时,第一个父类有 vtable → 子类启用; # 父类无 vtable → 子类静态;父类信息未知 → 保守启用。 if not is_cvtable and not is_novtable and first_parent_vtable is not None: if first_parent_vtable: @@ -2985,8 +2919,8 @@ class ExprCallHandle(BaseHandle): # VtableByClassLevel:**忽略方法级 CVTable 标记**算出的 vtable 状态 # (= 类级 CVTable / 继承链判定)——供槽位筛选与"方法级触发"共用。 _VtByClassLevel: bool = is_cvtable - # 方法级修饰符筛选:`novirtual def`(⇒ @t.NoVTable)不进槽; - # `virtual def`(⇒ @t.CVTable)进槽。判据唯一源 = IsVtableSlotMethod + # 方法级修饰符筛选:`novirtual def`(⇒ @NoVTable)不进槽; + # `virtual def`(⇒ @CVTable)进槽。判据唯一源 = IsVtableSlotMethod # (与定义端 HandlesClassDef / VPC _should_method_be_virtual 同口径), # 故跨模块虚表槽序与定义模块逐槽一致。 self_methods: list[str] = [] @@ -3064,7 +2998,7 @@ class ExprCallHandle(BaseHandle): 避免链接时 undefined reference。 触发场景:numpy 模块内部函数(如 np_sum)调用 a.sum(), - 其中 a 的类型注解 ndarray[t.CDouble] | t.CPtr 在类型解析时 + 其中 a 的类型注解 ndarray[CDouble] | CPtr 在类型解析时 只触发了 declare_only=True 特化(创建 struct + __before_init__), 方法体(fill/delete/dot/sum/...)未被编译。 """ @@ -3307,7 +3241,7 @@ class ExprCallHandle(BaseHandle): return self._HandleStaticMethodCallLlvm(Node, ClassName, MethodName) if FuncMeta.CLASS_METHOD in SymInfo.MetaList: return self._HandleStaticMethodCallLlvm(Node, ClassName, MethodName) - if isinstance(Node.func.value, ast.Name) and IsTModule(Node.func.value.id, self.Trans.SymbolTable): + if isinstance(Node.func.value, ast.Name) : result = self.Trans.TSpecialCallHandle._HandleTSpecialCallLlvm(Node) if result is not None: return result @@ -3322,8 +3256,7 @@ class ExprCallHandle(BaseHandle): target_bits = 0 is_float = getattr(ctype_inst, 'IsSigned', False) is None and target_bits > 0 if ctype_inst else False IsPtr_cast = len(Node.args) >= 2 and ( - (isinstance(Node.args[1], ast.Attribute) and Node.args[1].attr == 'CPtr' and isinstance(Node.args[1].value, ast.Name) and IsTModule(Node.args[1].value.id, self.Trans.SymbolTable)) or - (isinstance(Node.args[1], ast.Name) and Node.args[1].id == 'CPtr') + isinstance(Node.args[1], ast.Name) and Node.args[1].id == 'CPtr' ) if Node.args: ArgNode = Node.args[0] @@ -3376,52 +3309,6 @@ class ExprCallHandle(BaseHandle): SymInfo = self.Trans.SymbolTable[MethodName] if SymInfo.IsTypedef: return self._HandleTypedefCastLlvm(Node, MethodName) - if isinstance(Node.func.value, ast.Name) and Node.func.value.id == 'c': - if MethodName == 'Asm': - return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node) - if MethodName == 'Addr': - return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node) - elif MethodName == 'Set': - return self.Trans.CSpecialCallHandle._HandleCSetLlvm(Node) - elif MethodName == 'Load': - return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node) - elif MethodName == 'Deref': - return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node) - elif MethodName == 'DerefAs': - return self._HandleCDerefAsLlvm(Node) - elif MethodName == 'PtrToInt': - return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node) - elif MethodName in ('CIf', 'CIfdef', 'CIfndef', 'CElif'): - from lib.core.LLVMCG.FuncGen import FailFastError - raise FailFastError(_REMOVED_CIF_CALL_MSG) - elif MethodName == 'CError': - msg = "compile-time error" - if Node.args: - arg = Node.args[0] - if isinstance(arg, ast.Constant) and isinstance(arg.value, str): - msg = arg.value - else: - try: - val = self.HandleExprLlvm(arg) - if isinstance(val, str): - msg = val - except Exception as _e: - if _config_mode == "strict": - raise - _vlog().warning(f"处理函数调用失败: {_e}", "Exception") - lineno = getattr(Node, 'lineno', 0) - # 注入行偏移还原:AST 行号含 _inject_auto_imports 注入的 N 行 - _line_offset: int = int(getattr(self.Trans, '_line_offset', 0) or 0) - if _line_offset > 0 and lineno > _line_offset: - lineno -= _line_offset - raise Exception(f"#error: {msg} (line {lineno})") - elif MethodName in ('CElse', 'CEndif'): - from lib.core.LLVMCG.FuncGen import FailFastError - raise FailFastError(_REMOVED_CIF_CALL_MSG) - elif MethodName in ('CPragma', 'CUndef'): - return ir.Constant(ir.IntType(1), 1) - elif MethodName in ('LLVMIR', 'LInp', 'LOut'): - return None ObjVal = self.HandleExprLlvm(Node.func.value) if not ObjVal: return None @@ -3801,7 +3688,7 @@ class ExprCallHandle(BaseHandle): CallArgs[target_idx] = ArgVal # 按需 vtable 注册:当 ClassName 不在 vtable 集合中但有 class_sha1 时, - # 从 .pyi stub 检查 @t.CVTable 装饰器并注册。 + # 从 .pyi stub 检查 @CVTable 装饰器并注册。 # 修复场景:list[str].__new__ 中 pool.alloc(48) 编译时, # MemManager 可能因导入时序问题未注册到当前 Gen 的 vtable 集合, # 导致生成 call_(直接调用)而非 vcall_(虚分派),运行时段错误。 @@ -3818,8 +3705,8 @@ class ExprCallHandle(BaseHandle): # class_methods)与 struct body 可能因并行 include 翻译时序撕裂—— # _try_register_vtable_ondemand 只注册元数据不具化 body,若此时 struct # 仍 opaque,下方 GEP [0,0] 取 vtable 指针会抛 llvmlite 裸 TypeError - # (典型:list[AST|t.CPtr].append 中 self.__pool__.alloc(...), - # __pool__ 类型 memhub.MemManager|t.CPtr,MemManager 已进 vtable 集合 + # (典型:list[AST|CPtr].append 中 self.__pool__.alloc(...), + # __pool__ 类型 memhub.MemManager|CPtr,MemManager 已进 vtable 集合 # 但 struct body 未从 stub 具化)。 # 此处先主动具化(stub + class_members 双路径),仍失败则 fail-fast # 暴露上游 stub 加载时序问题,而非静默崩溃。 @@ -4182,7 +4069,7 @@ class ExprCallHandle(BaseHandle): offset = Gen._get_member_offset(len_member, bare_cls) len_ptr = Gen.builder.gep(self_ptr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=f"self_{len_member}_ptr") return Gen._load(len_ptr, name=f"self_{len_member}") - # 修复 stdint.vp 崩溃(0xC0000005)根因:`list[X] | t.CPtr` 联合字段 + # 修复 stdint.vp 崩溃(0xC0000005)根因:`list[X] | CPtr` 联合字段 # 的 LLVM 类型退化为 i8*,_HandleLenLlvm 无法识别为 list,fall through # 到 strlen 分支 → 对 list 对象指针执行 strlen → 垃圾长度 → 越界 get # → 垃圾指针 → strcmp 崩。此处按字段静态类型(class_member_element_class @@ -4307,21 +4194,21 @@ class ExprCallHandle(BaseHandle): 规则本体在 SymbolUtils.ResolveTypeArgStr(定义端/声明端唯一规则源, 声明端 DeclarationGenerator 的泛型分支亦调用同一函数),此处仅注入 翻译器上下文: - - t/c 导入别名表(from t import CInt as myint → 't.CInt') + - t/c 导入别名表(from t import CInt as myint → 'CInt') - 跨模块结构体 SHA1 表(ast.Name/Attribute 命中 → '{sha1}.{名}',与普通签名一致) """ Gen = self.Trans.LlvmGen StructSha1Map: dict[str, str] = getattr(Gen, '_struct_sha1_map', {}) if Gen is not None else {} return ResolveTypeArgStr( node, - TCAliasMap=getattr(self.Trans, '_t_c_imported_names', {}), + TCAliasMap=getattr(self.Trans, '_from_import_aliases', {}), StructSha1Map=StructSha1Map) def _get_raw_type_name(self, node: ast.AST) -> str: """获取类型节点的原始名称(不带模块前缀),用于泛型 T 替换。 ast.Name → sn.id (如 'AST', 'CInt') - ast.Attribute → sn.attr (如 t.CInt → 'CInt') + ast.Attribute → sn.attr (如 CInt → 'CInt') ast.BinOp → 左侧的原始名称 (如 AST | CPtr → 'AST') """ if isinstance(node, ast.Name): @@ -4336,14 +4223,14 @@ class ExprCallHandle(BaseHandle): """解析泛型 slice 中的单个类型参数节点,返回 (type_arg, type_name) 或 None。 type_arg: 用于 mangling,走**唯一规则源** _resolve_type_arg_str - (内层与参数注解同解析:'AST | t.CPtr' / 'rawptr[AST]' → + (内层与参数注解同解析:'AST | CPtr' / 'rawptr[AST]' → '{sha1}.AST*'、裸类名 'AST' → '{sha1}.AST'、标量按 NormalizeGenericArgName 归一) type_name: 用于替换泛型类型参数 T(原始源码名,如 'AST' / 'CInt', - _specialize_generic_class 会自动给类名加 | t.CPtr) - 指针下标 rawptr[T] 先折叠成等价的 `T | t.CPtr` 再解析, + _specialize_generic_class 会自动给类名加 | CPtr) + 指针下标 rawptr[T] 先折叠成等价的 `T | CPtr` 再解析, 与源码联合写法得到同一 (type_arg, type_name):否则 list[rawptr[ast.AST]] - 会拼出 'rawptr[ast.AST]' 实参串(内层未混淆)→ 与 list[ast.AST | t.CPtr] + 会拼出 'rawptr[ast.AST]' 实参串(内层未混淆)→ 与 list[ast.AST | CPtr] 的 '.AST*' 分裂成两个特化名(结构体/方法声明/调用点三端不一致)。 """ if IsPtrSubscriptNode(sn, self.Trans.SymbolTable): @@ -4353,16 +4240,14 @@ class ExprCallHandle(BaseHandle): # `list[X]`/`rawptr[X]` 内层收敛到同一名字); # type_name 保留源码名供 T 替换与内建/类类型判定(两张表收拢在 SymbolUtils) return (self._resolve_type_arg_str(sn), GenericArgRawName(sn.id)) - # BinOp (如 AST | CPtr) 或 Attribute (如 t.CPtr / t.CInt) + # BinOp (如 AST | CPtr) 或 Attribute (如 mod.CInt) type_str: str = self._resolve_type_arg_str(sn) - # type_name 保留模块前缀(如 't.CUnsignedChar'),避免 T(0) 替换为 + # type_name 保留源码名(如 'CUnsignedChar'),避免 T(0) 替换为 # CUnsignedChar(0) 后因 CUnsignedChar 不在顶层作用域而报 # "Undefined function: 'CUnsignedChar'"。 - # t.CPtr 特殊处理:保留 't.CPtr' 带前缀(2026-08-19 根修:此前裸 - # 'CPtr' 作为 type_map['T'] 替换进模板(item: T → item: CPtr)时, - # CPtr 不在顶层作用域 → 方法声明注册失败 → "Undefined method - # 'append' in class 'list[CPtr]'"。带前缀 't.CPtr' 可解析。 - # 指针参数识别改由 _BUILTIN_TYPE_NAMES 的 tn_bare 检测('t.CPtr'→'CPtr')。 + # CPtr 同样保留 'CPtr':作为 type_map['T'] 替换进模板(item: T → + # item: CPtr)时需要可解析;指针参数识别由 _BUILTIN_TYPE_NAMES 的 + # tn_bare 检测('CPtr'→'CPtr')。 if isinstance(sn, ast.Attribute) and isinstance(sn.value, ast.Name): raw_name: str = f'{sn.value.id}.{sn.attr}' else: @@ -4371,9 +4256,7 @@ class ExprCallHandle(BaseHandle): @staticmethod def _IsCPtrMark(Node: ast.AST) -> bool: - """`t.CPtr` / 裸名 `CPtr` 标记节点。""" - if isinstance(Node, ast.Attribute): - return Node.attr == 'CPtr' + """判断节点是否为 `CPtr` 标记(裸名)。""" if isinstance(Node, ast.Name): return Node.id == 'CPtr' return False @@ -4381,8 +4264,8 @@ class ExprCallHandle(BaseHandle): def _CallReturnClass(self, Node: ast.Call, Gen: LlvmGeneratorMixin) -> str | None: """调用结果的**被指类名**:从被调者的返回注解恢复。 - 背景:`list[str]*` ≡ `list[str] | t.CPtr`(只读探针已确认二者 AST 逐字同形, - 都是 `BinOp(BitOr, Subscript(...), Attribute(t.CPtr))`)这类返回注解在 LLVM 层 + 背景:`list[str]*` ≡ `list[str] | CPtr`(只读探针已确认二者 AST 逐字同形, + 都是 `BinOp(BitOr, Subscript(...), Attribute(CPtr))`)这类返回注解在 LLVM 层 被映射成通用指针 `i8*`,类名随之丢失 ⇒ 调用点只能按通用指针处理 (`parts = s1.split(',')` 之后 `parts[0]` 退化成按字节索引、得到整数,赋给 `str` 时报"整数隐式转指针已禁止",真因在 4 行之前)。 @@ -4414,11 +4297,11 @@ class ExprCallHandle(BaseHandle): return None def _ClassFromAnnotation(self, Ann: ast.AST, Gen: LlvmGeneratorMixin) -> str | None: - """从注解恢复"类名(含泛型特化名)":剔除 `| t.CPtr` 侧与指针层后取核类型。 + """从注解恢复"类名(含泛型特化名)":剔除 `| CPtr` 侧与指针层后取核类型。 - - `list[str] | t.CPtr` / `list[str]*` → `list[str]`(泛型特化名,与 + - `list[str] | CPtr` / `list[str]*` → `list[str]`(泛型特化名,与 HandlesAnnAssign:1012-1034 的构名方式一致); - - `Foo | t.CPtr` / `Foo*` → `Foo`; + - `Foo | CPtr` / `Foo*` → `Foo`; - 核类型名必须能在 `Gen.structs` / `Gen.class_members` 命中(含 sha1 前缀 全名的短名归一),否则返回 None(类型信息不完整时不硬塞名字)。 """ @@ -4502,7 +4385,7 @@ class ExprCallHandle(BaseHandle): f"泛型类注解 '{ast.unparse(Sub)}' 无法解析全部类型实参:" f"需要 {len(type_param_names)} 个,仅解析出 {len(type_args)} 个;" f"禁止按 int 兜底。") - # 类型注解解析(如 Float64Array: t.CTypedef = ndarray[t.CDouble]) + # 类型注解解析(如 Float64Array: CTypedef = ndarray[CDouble]) # 只需 struct 定义,不需方法体;使用 declare_only=True 避免过早触发 # 完整特化(此时被引用的函数如 printf 可能尚未由 from X import Y 注册, # 导致 "Undefined function" 错误)。完整特化由后续类实例化 @@ -4512,9 +4395,9 @@ class ExprCallHandle(BaseHandle): @staticmethod def _AnnotationContainsCPtr(Node: ast.AST) -> bool: - """检查类型注解 AST 是否包含 t.CPtr(即是否为指针类型)""" - if isinstance(Node, ast.Attribute): - if Node.attr == 'CPtr': + """检查类型注解 AST 是否包含 CPtr(即是否为指针类型)""" + if isinstance(Node, ast.Name): + if Node.id == 'CPtr': return True if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr): return (ExprCallHandle._AnnotationContainsCPtr(Node.left) @@ -4558,17 +4441,17 @@ class ExprCallHandle(BaseHandle): elif isinstance(Node, ast.Attribute): type_name = Node.attr elif isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr): - # 联合类型(如 X | t.CPtr):VPC 注解中 | = and,带 t.CPtr 的联合 + # 联合类型(如 X | CPtr):VPC 注解中 | = and,带 CPtr 的联合 # 是指针类型(X* 或 i8*),sizeof = 8(指针大小)。 - # list[T].__init__ 的 T.__sizeof__() 特化后 T 被还原为 'X | t.CPtr' + # list[T].__init__ 的 T.__sizeof__() 特化后 T 被还原为 'X | CPtr' # (_make_replacement_node),此前落到 else 返回 0 → elem_size=0 → # 所有元素存取同槽(get(0)==get(1),list[对象] join 误报根因)。 if _BinOpContainsCPtr(Node): return ir.Constant(ir.IntType(64), 8) - # 不带 t.CPtr 的联合(A | B)无法确定尺寸:曾静默返回 0 → + # 不带 CPtr 的联合(A | B)无法确定尺寸:曾静默返回 0 → # 下游 elem_size=0 → alloc(0) 返回 NULL / 所有元素存取同槽。fail-fast。 raise ValueError( - f"[FATAL][__sizeof__] 联合类型 '{ast.unparse(Node)}' 不含 t.CPtr," + f"[FATAL][__sizeof__] 联合类型 '{ast.unparse(Node)}' 不含 CPtr," f"无法确定尺寸,拒绝静默返回 0(会导致 alloc(0)/元素同槽)" ) else: @@ -4604,10 +4487,10 @@ class ExprCallHandle(BaseHandle): size_bits = getattr(ctype_inst, 'Size', 0) or 0 size_bytes = size_bits // 8 # POINTER 类型(CPtr 等)Size 为 None/0 → 指针大小 8。 - # 根因:t.CPtr.__sizeof__() 返回 0 → list[t.CPtr] + # 根因:CPtr.__sizeof__() 返回 0 → list[CPtr] # elem_size=0 → append 全写同槽/alloc(0) → 崩溃。 if getattr(ctype_inst, 'HasPosition', None) \ - and ctype_inst.HasPosition(t.CType.POINTER) \ + and ctype_inst.HasPosition(TypeSystem.CType.POINTER) \ and size_bytes == 0: size_bytes = 8 return ir.Constant(ir.IntType(64), size_bytes) @@ -4936,10 +4819,10 @@ class ExprCallHandle(BaseHandle): return ir.Constant(ir.IntType(32), 0) def _HandleCDerefAsLlvm(self, Node: ast.Call) -> ir.Value | None: - """c.DerefAs(p, v):bitcast **指针** p 到 typeof(v)* 后按值存 v(`*(T*(p)) = v`)。 + """DerefAs(p, v):bitcast **指针** p 到 typeof(v)* 后按值存 v(`*(T*(p)) = v`)。 与 ViperC CallGenCBuiltin.translate_c_derefas 逐字同口径: - - 单参形式(len<2)是**解引用读取**(等同 c.Deref(p)); + - 单参形式(len<2)是**解引用读取**(等同 Deref(p)); - 双参:p、v 均为指针且 p 的 pointee 是结构体且与 v 的 pointee **同一**时, 按整对象拷贝(load v 指向的对象 + bitcast p + store);否则 bitcast p 到 typeof(v)* 后按值 store v。 @@ -5435,7 +5318,7 @@ class ExprCallHandle(BaseHandle): obj_val = self.HandleExprLlvm(Node.value) idx_val = self.HandleExprLlvm(Node.slice) if obj_val and idx_val: - # 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8 + # 处理 obj_val 为 i8(整数)的情况:联合类型 | CPtr 降级后可能被 load 为 i8 if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8: obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}") if self._is_char_pointer(obj_val): diff --git a/lib/core/Handles/HandlesExprLambda.py b/lib/core/Handles/HandlesExprLambda.py index d997469..30da38a 100644 --- a/lib/core/Handles/HandlesExprLambda.py +++ b/lib/core/Handles/HandlesExprLambda.py @@ -207,7 +207,7 @@ class ExprLambdaHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:条件表达式两分支类型不一致({BodyVal.type} / {result_type});" - f"如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{Gen._DescribeValueNode(Node.body)}" ) Gen.builder.branch(MergeBB) @@ -239,7 +239,7 @@ class ExprLambdaHandle(BaseHandle): from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:条件表达式两分支类型不一致({OrelseVal.type} / {result_type});" - f"如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{Gen._DescribeValueNode(Node.orelse)}" ) Gen.builder.branch(MergeBB) diff --git a/lib/core/Handles/HandlesExprOps.py b/lib/core/Handles/HandlesExprOps.py index 2917500..69e15e7 100644 --- a/lib/core/Handles/HandlesExprOps.py +++ b/lib/core/Handles/HandlesExprOps.py @@ -365,7 +365,7 @@ class ExprOpsHandle(BaseHandle): if RightVal: ClassName: str | None = self.Trans.ExprHandler._get_var_class(Node.comparators[0], Gen) if ClassName and Gen._has_function(f'{ClassName}.__contains__'): - # 处理 RightVal 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8 + # 处理 RightVal 为 i8(整数)的情况:联合类型 | CPtr 降级后可能被 load 为 i8 if isinstance(RightVal.type, ir.IntType) and RightVal.type.width == 8: RightVal = Gen.builder.inttoptr(RightVal, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}") if isinstance(RightVal.type, ir.PointerType) and isinstance(RightVal.type.pointee, ir.IntType) and RightVal.type.pointee.width == 8: diff --git a/lib/core/Handles/HandlesExprUtils.py b/lib/core/Handles/HandlesExprUtils.py index 1b63814..c80f7d0 100644 --- a/lib/core/Handles/HandlesExprUtils.py +++ b/lib/core/Handles/HandlesExprUtils.py @@ -5,9 +5,6 @@ if TYPE_CHECKING: from lib.core.LlvmCodeGenerator import LlvmCodeGenerator import vast as ast import llvmlite.ir as ir -from lib.core.SymbolUtils import IsTModule - - class ExprUtils: def __init__(self, translator: "Translator") -> None: self.Trans: Translator = translator @@ -194,7 +191,7 @@ class ExprUtils: if not Gen._has_function(FullMethodName): # 泛型特化 fallback:当 ClassName 是 opaque 基础名(如 'ndarray')且 # 无直接匹配方法时,遍历 Gen.structs 查找以 'ClassName[' 开头的特化版本 - # (如 'ndarray[double]')。注解 'numpy.ndarray | t.CPtr' 未指定类型参数时, + # (如 'ndarray[double]')。注解 'numpy.ndarray | CPtr' 未指定类型参数时, # var_struct_class 仅记录裸模板名,但方法只在特化版本中定义。 # 选择策略:优先选 obj_val.type.pointee 实际匹配的特化;否则选第一个有方法的特化。 if '[' not in ClassName: @@ -393,13 +390,10 @@ class ExprUtils: return ir.IntType(32) if func_name == 'float' or func_name == 'double': return ir.DoubleType() - elif isinstance(node.func, ast.Attribute): - if isinstance(node.func.value, ast.Name) and node.func.value.id == 'c': - if node.func.attr == 'Deref': - return ir.IntType(64) - if isinstance(node.func.value, ast.Name) and IsTModule(node.func.value.id, self.Trans.SymbolTable): - if node.func.attr == 'CChar': - return ir.PointerType(ir.IntType(8)) + if func_name == 'Deref': + return ir.IntType(64) + if func_name == 'CChar': + return ir.PointerType(ir.IntType(8)) return ir.IntType(32) elif isinstance(node, ast.Compare): return ir.IntType(1) diff --git a/lib/core/Handles/HandlesFor.py b/lib/core/Handles/HandlesFor.py index d7a2dbb..f23d03d 100644 --- a/lib/core/Handles/HandlesFor.py +++ b/lib/core/Handles/HandlesFor.py @@ -111,12 +111,10 @@ class ForHandle(BaseHandle): if StepVal is None: StepVal = ir.Constant(EndVal.type, 1) if not IsRange: - # 检测 c.Addr(x) 模式:按原始变量类型迭代(for i64 in i64* 语义) + # 检测 Addr(x) 模式:按原始变量类型迭代(for i64 in i64* 语义) if (isinstance(Node.iter, ast.Call) - and isinstance(Node.iter.func, ast.Attribute) - and isinstance(Node.iter.func.value, ast.Name) - and Node.iter.func.value.id == 'c' - and Node.iter.func.attr == 'Addr' + and isinstance(Node.iter.func, ast.Name) + and Node.iter.func.id == 'Addr' and Node.iter.args): AddrArg: ast.expr = Node.iter.args[0] if isinstance(AddrArg, ast.Name) and AddrArg.id in Gen.variables: @@ -547,7 +545,7 @@ class ForHandle(BaseHandle): def _HandleForPtrLlvm(self, Node: ast.For, PtrVal: ir.Value, ElemType: ir.IntType) -> None: """通用指针迭代:按 ElemType 大小逐元素迭代,终止条件为元素值 == 0 - 适用于 for i in c.Addr(u) where u: i32/i64 等非 i8 整数类型。 + 适用于 for i in Addr(u) where u: i32/i64 等非 i8 整数类型。 """ Gen: "Translator.LlvmGen" = self.Trans.LlvmGen if not isinstance(Node.target, ast.Name): @@ -750,12 +748,10 @@ class ForHandle(BaseHandle): if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Name) and arg.func.id == 'range': return self._zip_setup_range(arg, target_name, Gen) - # Case 2: c.Addr(x) — 指针/数组迭代 + # Case 2: Addr(x) — 指针/数组迭代 if (isinstance(arg, ast.Call) - and isinstance(arg.func, ast.Attribute) - and isinstance(arg.func.value, ast.Name) - and arg.func.value.id == 'c' - and arg.func.attr == 'Addr' + and isinstance(arg.func, ast.Name) + and arg.func.id == 'Addr' and arg.args): AddrArg: ast.expr = arg.args[0] if isinstance(AddrArg, ast.Name) and AddrArg.id in Gen.variables: diff --git a/lib/core/Handles/HandlesFunctions.py b/lib/core/Handles/HandlesFunctions.py index 72234da..a5fc78d 100644 --- a/lib/core/Handles/HandlesFunctions.py +++ b/lib/core/Handles/HandlesFunctions.py @@ -9,25 +9,25 @@ import traceback import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta from lib.core.SymbolUtils import ( - IsTModule, FindStructNameInAnnotationWithContext, AnnotationContainsName, + FindStructNameInAnnotationWithContext, AnnotationContainsName, IsPtrSubscriptNode, DesugarPtrSubscriptToUnion, FindAutoAddrMode) from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode -from lib.includes import t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry -# t 模块存储类标记装饰器名称集合 +# 内建存储类标记装饰器名称集合 _T_STORAGE_DECORATORS = frozenset({'CExport', 'CExtern', 'CStatic', 'State', 'CInline', 'TLS'}) -# `@c.CReturn` 装饰器已移除;任何地方遇到都必须 fail-fast,不得静默忽略或改写。 +# `@CReturn` 装饰器已移除;任何地方遇到都必须 fail-fast,不得静默忽略或改写。 _CRETURN_REMOVED_HINT: str = ( - "`@c.CReturn` 已移除:请改用返回注解 `-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)" + "`@CReturn` 已移除:请改用返回注解 `-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)" ) def _RejectCReturnDecorator(node: ast.AST, decorators: list[ast.AST]) -> None: - """扫到 `@c.CReturn` 装饰器即 fail-fast 报错(该装饰器已移除)。""" + """扫到 `@CReturn` 装饰器即 fail-fast 报错(该装饰器已移除)。""" for decorator in decorators: if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute): if decorator.func.attr == 'CReturn': @@ -53,9 +53,9 @@ def _RejectRefReturnAnnotation(node: ast.AST) -> None: def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool: """判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。 - void:None / t.CVoid,含 `|` 联合形式(注解中 `|` 表示 and), - 如 `-> t.CVoid | t.CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。 - 声明型辅助符号:t.State(extern)/ t.CExport(export)/ t.CExtern—— + void:None / CVoid,含 `|` 联合形式(注解中 `|` 表示 and), + 如 `-> CVoid | CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。 + 声明型辅助符号:State(extern)/ CExport(export)/ CExtern—— 此类函数返回注解被改写为 `<原类型> | 辅助符号` 且 body 为空(extern 声明), 掉出末尾是正常形态,必须豁免 fail-fast。 """ @@ -71,9 +71,9 @@ def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool: def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool: """判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。 - void:None / t.CVoid,含 `|` 联合形式(注解中 `|` 表示 and), - 如 `-> t.CVoid | t.CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。 - 声明型辅助符号:t.State(extern)/ t.CExport(export)/ t.CExtern—— + void:None / CVoid,含 `|` 联合形式(注解中 `|` 表示 and), + 如 `-> CVoid | CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。 + 声明型辅助符号:State(extern)/ CExport(export)/ CExtern—— 此类函数返回注解被改写为 `<原类型> | 辅助符号` 且 body 为空(extern 声明), 掉出末尾是正常形态,必须豁免 fail-fast。 """ @@ -114,10 +114,10 @@ class FunctionHandle(BaseHandle): return meta def _extract_decorator_storage_flags(self, Node: ast.FunctionDef) -> dict[str, bool]: - """从装饰器列表中提取 t 模块存储类标记 + """从装饰器列表中提取内建存储类标记 - 支持 @t.CExport, @t.CExtern, @t.CStatic, @t.State, @t.CInline - 也支持 from t import CExport 等别名形式 + 支持 @CExport, @CExtern, @CStatic, @State, @CInline + 内建标记按裸名书写,如 @CExport。 Returns: dict with keys: 'is_export', 'is_extern', 'is_static', 'is_state', 'is_inline' @@ -131,16 +131,12 @@ class FunctionHandle(BaseHandle): symtab: object = self.Trans.SymbolTable for decorator in Node.decorator_list: attr_name: str | None = None - # @t.CExport 形式 - if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name): - if IsTModule(decorator.value.id, symtab): - attr_name = decorator.attr - # @CExport 形式 (from t import CExport) - elif isinstance(decorator, ast.Name): - cls: type | None = getattr(t, decorator.id, None) - if cls is None and hasattr(symtab, '_t_type_symbols'): - cls = symtab._t_type_symbols.get(decorator.id) - if cls is not None and isinstance(cls, type) and issubclass(cls, t.CType): + # 内建标记按裸名书写(@CExport / @CStatic / ...) + if isinstance(decorator, ast.Name): + cls: type | None = getattr(TypeSystem, decorator.id, None) + if cls is None and hasattr(symtab, '_builtin_type_symbols'): + cls = symtab._builtin_type_symbols.get(decorator.id) + if cls is not None and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): attr_name = cls.__name__ if attr_name and attr_name in _T_STORAGE_DECORATORS: if attr_name == 'CExport': @@ -157,18 +153,15 @@ class FunctionHandle(BaseHandle): @staticmethod def _is_t_storage_decorator(decorator: ast.AST, symtab: object) -> bool: - """检查装饰器是否是 t 模块存储类标记(用于排除 behavior_decorators)""" + """检查装饰器是否是内建存储类标记(用于排除 behavior_decorators)""" attr_name: str | None = None - if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name): - if IsTModule(decorator.value.id, symtab): - attr_name = decorator.attr - elif isinstance(decorator, ast.Name): - cls: type | None = getattr(t, decorator.id, None) - if cls is None and hasattr(symtab, '_t_type_symbols'): - cls = symtab._t_type_symbols.get(decorator.id) - if cls is not None and isinstance(cls, type) and issubclass(cls, t.CType): + if isinstance(decorator, ast.Name): + cls: type | None = getattr(TypeSystem, decorator.id, None) + if cls is None and hasattr(symtab, '_builtin_type_symbols'): + cls = symtab._builtin_type_symbols.get(decorator.id) + if cls is not None and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): attr_name = cls.__name__ - elif decorator.id in _T_STORAGE_DECORATORS and hasattr(t, decorator.id): + elif decorator.id in _T_STORAGE_DECORATORS and hasattr(TypeSystem, decorator.id): # TLS 是普通函数标记,不是 CType 子类 attr_name = decorator.id return attr_name in _T_STORAGE_DECORATORS if attr_name else False @@ -335,9 +328,7 @@ class FunctionHandle(BaseHandle): if not isinstance(value, ast.Attribute) or value.attr != 'llvm': return None inner: ast.AST = value.value - if not isinstance(inner, ast.Attribute) or inner.attr != 'attr': - return None - if not isinstance(inner.value, ast.Name) or inner.value.id != 't': + if not isinstance(inner, ast.Name) or inner.id != 'attr': return None return node.attr @@ -507,7 +498,7 @@ class FunctionHandle(BaseHandle): var_info: Any = self.Trans.SymbolTable.lookup(var_name) if var_info and isinstance(var_info, dict): var_type: str = var_info.get('type', '') - if var_type.startswith('list[') or var_type.startswith('List[') or var_type.startswith('t.CArray['): + if var_type.startswith('list[') or var_type.startswith('List[') or var_type.startswith('CArray['): inner: str = var_type[var_type.index('[') + 1:var_type.rindex(']')] parts: list[str] = inner.split(',') elem_type_str: str = parts[0].strip() @@ -540,14 +531,14 @@ class FunctionHandle(BaseHandle): if Node.returns: if MultiRetTypes: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() else: try: if isinstance(Node.returns, ast.BinOp) and isinstance(Node.returns.op, ast.BitOr): ReturnTypeInfo = getattr(self.Trans, 'TypeMergeHandler', None) and self.Trans.TypeMergeHandler.MergeTypes(Node.returns) if not isinstance(ReturnTypeInfo, CTypeInfo): ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() if ((ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState) or (ReturnTypeInfo.PtrCount >= 2 and ReturnTypeInfo.BaseType is None)): def _FindNonVoidCTypeInfo(node: ast.AST) -> Any: @@ -574,9 +565,9 @@ class FunctionHandle(BaseHandle): ReturnTypeInfo = found if ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() - # define 宏函数(返回注解含 t.CDefine,如 `int | t.CDefine`): - # 标记为编译期内联宏(alwaysinline),对齐裸 `-> t.CDefine` 路径 + ReturnTypeInfo.BaseType = TypeSystem.CInt() + # define 宏函数(返回注解含 CDefine,如 `int | CDefine`): + # 标记为编译期内联宏(alwaysinline),对齐裸 `-> CDefine` 路径 # (合并路径丢失 IsDefine 时仍能命中) if AnnotationContainsName(Node.returns, 'CDefine'): if not hasattr(self, '_cdefine_funcs'): @@ -587,7 +578,7 @@ class FunctionHandle(BaseHandle): if isinstance(Node.returns, ast.Name) and Node.returns.id in ('str', 'bytes'): is_str_type = True # 走 ResolveAnnotationType 而非 CTypeInfo.FromNode:指针下标 - # 返回注解(rawptr[T] / t.CPtr[T])需走 TypeMerge 通用解析, + # 返回注解(rawptr[T] / CPtr[T])需走 TypeMerge 通用解析, # 否则内层跨模块类解析不出 → CVoid/1(i8*)。 ReturnTypeInfo = self.ResolveAnnotationType(Node.returns) if ReturnTypeInfo and ReturnTypeInfo.IsDefine: @@ -597,28 +588,28 @@ class FunctionHandle(BaseHandle): ReturnTypeInfo.PtrCount = 1 if inferred[1] else 0 else: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() if not hasattr(self, '_cdefine_funcs'): self._cdefine_funcs = set() self._cdefine_funcs.add(FuncName) elif ReturnTypeInfo and ReturnTypeInfo.IsState: - if ReturnTypeInfo.PtrCount > 0 or (ReturnTypeInfo.BaseType and not isinstance(ReturnTypeInfo.BaseType, t.CVoid)): + if ReturnTypeInfo.PtrCount > 0 or (ReturnTypeInfo.BaseType and not isinstance(ReturnTypeInfo.BaseType, TypeSystem.CVoid)): pass else: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() if ReturnTypeInfo is None: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() # 仅指针层数 <=1 才算裸 str/bytes(i8*)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 if is_str_type or (ReturnTypeInfo.IsStr and ReturnTypeInfo.PtrCount <= 1): ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CChar() + ReturnTypeInfo.BaseType = TypeSystem.CChar() ReturnTypeInfo.PtrCount = 1 # 检查泛型类返回类型 (如 list[str]) # 注意:_from_node_subscript 对未识别的泛型下标(如 list[str])返回空 CTypeInfo(BaseType=None), - # 此时 IsVoid 为 False(因为 IsVoid 仅检查 t.CVoid 实例),需额外检测 BaseType is None + # 此时 IsVoid 为 False(因为 IsVoid 仅检查 CVoid 实例),需额外检测 BaseType is None if (isinstance(Node.returns, ast.Subscript) and isinstance(Node.returns.value, ast.Name) and hasattr(self.Trans.ClassHandler, '_generic_class_templates') @@ -652,17 +643,17 @@ class FunctionHandle(BaseHandle): ret_class, ret_type_args, Gen, type_names=ret_type_names, declare_only=True) if spec_name2 and spec_name2 in Gen.structs: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CStruct(name=spec_name2) + ReturnTypeInfo.BaseType = TypeSystem.CStruct(name=spec_name2) ReturnTypeInfo.PtrCount = 1 if (ReturnTypeInfo.IsVoid or ReturnTypeInfo.BaseType is None) and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() except Exception: # 回退:设置默认返回类型为 CInt ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() else: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() inferred: Any = self._infer_return_type_from_body(Node, Gen, ClassName) if inferred: ReturnTypeInfo = CTypeInfo.FromTypeName(inferred[0]) @@ -670,7 +661,7 @@ class FunctionHandle(BaseHandle): IsPtr = ReturnTypeInfo.IsPtr if ReturnTypeInfo else False ReturnType: ir.Type = Gen._ctype_to_llvm(ReturnTypeInfo) # 此处原有 "Ptr(Ptr(Struct)) → Ptr(Struct)" 的压层(历史遗留):会把已解析的 - # 多层指针返回类型(`-> rawptr[rawptr[X]]` / `-> X | t.CPtr | t.CPtr`) + # 多层指针返回类型(`-> rawptr[rawptr[X]]` / `-> X | CPtr | CPtr`) # 与泛型特化方法返回(`list[X**]` 的 get/pop/__getitem__/__next__)少算一层, # 与同函数的形参(`append(item: T)` 保留 `X**`)、声明端 # DeclarationGenerator._get_type_str 的 BinOp 分支(同样不压层,见 @@ -703,14 +694,14 @@ class FunctionHandle(BaseHandle): for i, ReturnTypeNode in enumerate(MultiRetTypes): ReturnTypeInfo = CTypeInfo.FromNode(ReturnTypeNode, self.Trans.SymbolTable) # 仅指针层数 <=1 才算裸 str/bytes(i8*)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 if ReturnTypeInfo and ReturnTypeInfo.IsStr and ReturnTypeInfo.PtrCount <= 1: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CChar() + ReturnTypeInfo.BaseType = TypeSystem.CChar() ReturnTypeInfo.PtrCount = 1 if ReturnTypeInfo is None: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() RetType: ir.Type = Gen._ctype_to_llvm(ReturnTypeInfo) MultiRetLlvmTypes.append(RetType) ReturnType = ir.LiteralStructType(MultiRetLlvmTypes) @@ -727,20 +718,20 @@ class FunctionHandle(BaseHandle): ParamTypeInfo = self.ResolveParamAnnotation(Arg.annotation) if ParamTypeInfo is None: ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CInt() + ParamTypeInfo.BaseType = TypeSystem.CInt() IsPtr = ParamTypeInfo.IsPtr if ParamTypeInfo and getattr(ParamTypeInfo, 'IsCpythonObject', False) and not IsPtr: IsPtr = True ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1) # 仅当指针层数 <=1 时才压平为 i8*(裸 str/bytes)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), # 不能压平,否则形参类型错误导致 _adjust_args 多 load 一层崩溃。 if (ParamTypeInfo.IsStr and ParamTypeInfo.PtrCount <= 1) or (isinstance(Arg.annotation, ast.Name) and Arg.annotation.id in ('str', 'bytes')): ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CChar() + ParamTypeInfo.BaseType = TypeSystem.CChar() ParamTypeInfo.PtrCount = 1 IsPtr = True - # C 语言中数组参数退化为指针:t.CArray[type, N] → type* + # C 语言中数组参数退化为指针:CArray[type, N] → type* if ParamTypeInfo.ArrayDims: ParamTypeInfo.ArrayDims = [] ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1) @@ -751,7 +742,7 @@ class FunctionHandle(BaseHandle): AnnStr: str = ast.unparse(Arg.annotation) if hasattr(ast, 'unparse') else str(Arg.annotation) raise SyntaxError( f"无法识别的参数类型注解: '{AnnStr}'(在函数 '{Node.name}' 的参数 '{Arg.arg}' 上)。" - f"请使用有效的 VPC 类型(如 t.CPtr、ast.AST 或已注册的结构体)。" + f"请使用有效的 VPC 类型(如 CPtr、ast.AST 或已注册的结构体)。" ) ParamTypeStr: Any = ParamTypeInfo except SyntaxError: @@ -759,7 +750,7 @@ class FunctionHandle(BaseHandle): except Exception as e: ParamType = ir.IntType(32) ParamTypeStr = CTypeInfo() - ParamTypeStr.BaseType = t.CInt() + ParamTypeStr.BaseType = TypeSystem.CInt() else: if ClassName and Arg.arg != 'self': op_method_names: list[str] = ['__add__', '__sub__', '__mul__', '__truediv__', '__floordiv__', '__mod__', '__pow__', @@ -774,13 +765,13 @@ class FunctionHandle(BaseHandle): else: ParamType = ir.IntType(32) ParamTypeStr = CTypeInfo() - ParamTypeStr.BaseType = t.CInt() + ParamTypeStr.BaseType = TypeSystem.CInt() ParamTypes.append(ParamType) ParamNames.append(Arg.arg) ParamTypeStrs.append(ParamTypeStr) # 自动取址模式(由注解读出,不依赖 BaseType 类型): - # 'ref' = &T、'temp' = &temp T(合成联合 T | t.CRef / t.CTempRef), - # 'always' = t.CAutoPtr。经 Gen._auto_addr_params 供调用点分流。 + # 'ref' = &T、'temp' = &temp T(合成联合 T | CRef / CTempRef), + # 'always' = CAutoPtr。经 Gen._auto_addr_params 供调用点分流。 auto_mode: str | None = FindAutoAddrMode(Arg.annotation) auto_addr_modes.append(auto_mode) if self._apply_struct_self_cls_types(ParamTypes, ParamNames, IsMethod, IsClassMethod, ResolvedClassName, Gen): @@ -861,21 +852,21 @@ class FunctionHandle(BaseHandle): def _make_replacement_node(self, replacement: str) -> ast.AST: """将 type_map 中的替换字符串转换为 AST 节点。 - mangled 名称如 '.AST*' 需要还原为 AST | t.CPtr 结构, + mangled 名称如 '.AST*' 需要还原为 AST | CPtr 结构, 否则类型解析会丢失 PtrCount 信息。 含点号的名称(如 '.AST')需解析为 ast.Attribute 链。 下标形态('rawptr[ast.AST]' / 'list[AST]' 等)必须整体解析为 Subscript: _make_name_node 只按 '.' 切分会把 'rawptr[ast.AST]' 拆成 Name('rawptr[ast') + Attribute('AST]'),两段都不是有效类型名 → 参数/返回注解解析为空 → VoidType → "无法识别的参数类型注解"。 - 指针下标(rawptr[T] / t.CPtr[T])再折叠为等价的 `T | t.CPtr`,与源码 + 指针下标(rawptr[T] / CPtr[T])再折叠为等价的 `T | CPtr`,与源码 联合写法同解析路径(对齐 VPC TypeGenResolve._parse_type_string 的 '[' 分支 + ClassGenGeneric._clone_annotation 的 T 替换)。 内层为已混淆名(数字开头,如 'rawptr[7565e081d88517ac.AST]')时 ast.parse 无法解析(数字开头的令牌),改用手工拆 base/slice(同 VPC TypeGenResolve._parse_type_string 的数字开头手工拆分分支)。 尾部 '*'(泛型实参 '.Node*' / '.Node**',来自 rawptr[T] / - t.CPtr 的逐层 mangling)逐层还原为 `Node | t.CPtr [| t.CPtr]` → 对应 + CPtr 的逐层 mangling)逐层还原为 `Node | CPtr [| CPtr]` → 对应 层数指针;只剥一层会把 'Node*' 当结构体名建出 phantom opaque (item 类型与特化名 '.Node**' 的语义不一致)。 尾部 'ptr'(旧规则 mangling,如 'Nodeptr' / 'ast.ASTptr')保留兼容: @@ -886,9 +877,8 @@ class FunctionHandle(BaseHandle): BaseName: str = replacement[:len(replacement) - StarCount] base_node: ast.AST if BaseName in ('i8', 'void', 'void*'): - # i8*(void*)在源码侧写作 t.CPtr;再叠加 StarCount-1 层 - base_node = ast.Attribute( - value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load()) + # i8*(void*)在源码侧写作 CPtr;再叠加 StarCount-1 层 + base_node = ast.Name(id='CPtr', ctx=ast.Load()) StarCount -= 1 else: base_node = self._make_name_node(BaseName) @@ -897,9 +887,7 @@ class FunctionHandle(BaseHandle): node = ast.BinOp( left=node, op=ast.BitOr(), - right=ast.Attribute( - value=ast.Name(id='t', ctx=ast.Load()), - attr='CPtr', ctx=ast.Load()), + right=ast.Name(id='CPtr', ctx=ast.Load()), ) return node if replacement.endswith('ptr'): @@ -914,9 +902,7 @@ class FunctionHandle(BaseHandle): node = ast.BinOp( left=node, op=ast.BitOr(), - right=ast.Attribute( - value=ast.Name(id='t', ctx=ast.Load()), - attr='CPtr', ctx=ast.Load()), + right=ast.Name(id='CPtr', ctx=ast.Load()), ) return node if '[' in replacement: @@ -1054,21 +1040,21 @@ class FunctionHandle(BaseHandle): if isinstance(node, ast.Call): if isinstance(node.func, ast.Name) and node.func.id in type_map: replacement: str = type_map[node.func.id] - # 使用 _make_replacement_node 处理含点号的类型名(如 't.CUnsignedChar'), + # 使用 _make_replacement_node 处理含点号的类型名(如 'CUnsignedChar'), # 避免 T(0) 替换为 CUnsignedChar(0) 后因 CUnsignedChar 不在顶层作用域 # 而报 "Undefined function: 'CUnsignedChar'" node.func = self._make_replacement_node(replacement) elif isinstance(node.func, ast.Attribute): if isinstance(node.func.value, ast.Name) and node.func.value.id in type_map: replacement: str = type_map[node.func.value.id] - # 指针类型参数(如 list[AST | t.CPtr] 中的 T)在表达式上下文中 - # 需替换为 BinOp(AST | t.CPtr),使 __sizeof__ 等处理器能正确识别 + # 指针类型参数(如 list[AST | CPtr] 中的 T)在表达式上下文中 + # 需替换为 BinOp(AST | CPtr),使 __sizeof__ 等处理器能正确识别 # 指针语义并直接返回 8,避免触发 struct 加载和重入编译 if cptr_params and node.func.value.id in cptr_params: node.func.value = ast.BinOp( left=self._make_name_node(replacement), op=ast.BitOr(), - right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load()) + right=ast.Name(id='CPtr', ctx=ast.Load()) ) else: node.func.value = self._make_name_node(replacement) @@ -1083,7 +1069,7 @@ class FunctionHandle(BaseHandle): node.value = ast.BinOp( left=self._make_name_node(replacement), op=ast.BitOr(), - right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load()) + right=ast.Name(id='CPtr', ctx=ast.Load()) ) else: node.value = ast.Name(id=replacement, ctx=ast.Load()) @@ -1153,7 +1139,7 @@ class FunctionHandle(BaseHandle): RetTypeInfo = self.Trans.TypeMergeHandler.MergeTypes(Node.returns) else: RetTypeInfo = CTypeInfo.FromNode(Node.returns, self.Trans.SymbolTable) - if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExport): + if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, TypeSystem.CExport): has_cexport = True except Exception as _e: if _config_mode == "strict": @@ -1235,19 +1221,19 @@ class FunctionHandle(BaseHandle): try: RetTypeInfo: Any = None RetTypeInfo = self.ResolveAnnotationType(Node.returns) - if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExport) and not RetTypeInfo.IsState: + if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, TypeSystem.CExport) and not RetTypeInfo.IsState: Gen._export_funcs.add(FuncName) IsUserMarkedExport = True - if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExtern): + if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, TypeSystem.CExtern): Gen._export_funcs.add(FuncName) IsUserMarkedExport = True if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.IsState: - Gen._export_funcs.add(FuncName) # t.State 标记的函数必须保持原始名称,以便链接器解析 + Gen._export_funcs.add(FuncName) # State 标记的函数必须保持原始名称,以便链接器解析 IsUserMarkedExport = True except Exception as _e: if _config_mode == "strict": self.Trans.LogWarning(f"异常被忽略: {_e}") - # 装饰器形式的存储类标记(@t.CExport / @t.CExtern / @t.State 等) + # 装饰器形式的存储类标记(@CExport / @CExtern / @State 等) deco_flags: dict[str, bool] = self._extract_decorator_storage_flags(Node) if deco_flags['is_export'] or deco_flags['is_extern'] or deco_flags['is_state']: Gen._export_funcs.add(FuncName) @@ -1401,11 +1387,11 @@ class FunctionHandle(BaseHandle): # 另含**编译期生命期标注**(P2):@life(willFree(...)) 与 @willFree(...) 是纯标注, # 没有运行时装饰器函数;不排除会生成 wrapper 去调用不存在的 @life/@willFree, # 并把被装饰的 extern def(如 stdlib.free)变成本模块 internal 声明(llc 报 linkage 错)。 - _BUILTIN_DECORATORS = {'staticmethod', 'property', 'classmethod', 'life', 'willFree'} + _BUILTIN_DECORATORS = {'staticmethod', 'property', 'classmethod', 'life', 'willFree', 'Attribute'} _symtab: object = self.Trans.SymbolTable if Node.decorator_list: for decorator in Node.decorator_list: - # 跳过 t 模块存储类标记装饰器(@t.CExport / @CExport 等) + # 跳过内建存储类标记装饰器(@CExport / @CStatic 等) if self._is_t_storage_decorator(decorator, _symtab): continue # 识别自定义行为装饰器:@name(ast.Name 形式) @@ -1426,13 +1412,13 @@ class FunctionHandle(BaseHandle): deco_info['kwargs'][kw.arg] = kw.value.value behavior_decorators.append(deco_info) continue - if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute): - if decorator.func.attr == 'CReturn': + if isinstance(decorator, ast.Call): + if isinstance(decorator.func, ast.Attribute) and decorator.func.attr == 'CReturn': _RejectCReturnDecorator(Node, [decorator]) - elif decorator.func.attr == 'Attribute' and isinstance(decorator.func.value, ast.Name) and decorator.func.value.id == 'c': + elif isinstance(decorator.func, ast.Name) and decorator.func.id == 'Attribute': for arg in decorator.args: if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Attribute): - if isinstance(arg.func.value, ast.Attribute) and isinstance(arg.func.value.value, ast.Name) and IsTModule(arg.func.value.value.id, self.Trans.SymbolTable) and arg.func.value.attr == 'attr': + if isinstance(arg.func.value, ast.Name) and arg.func.value.id == 'attr': attr_name = arg.func.attr str_args = [a.value for a in arg.args if isinstance(a, ast.Constant) and isinstance(a.value, str)] int_args = [a.value for a in arg.args if isinstance(a, ast.Constant) and isinstance(a.value, int)] @@ -1445,28 +1431,30 @@ class FunctionHandle(BaseHandle): elif attr_name in ('noreturn', 'always_inline', 'noinline', 'cold', 'hot', 'constructor', 'destructor', 'pure', 'const', 'malloc', 'returns_nonnull', 'used', 'naked', 'no_instrument_function', 'warn_unused_result', 'weak', 'fallthrough'): if not arg.args: fn_attrs[attr_name] = True - elif isinstance(arg.func.value, ast.Attribute) and arg.func.value.attr == 'llvm' and isinstance(arg.func.value.value, ast.Attribute) and arg.func.value.value.attr == 'attr' and isinstance(arg.func.value.value.value, ast.Name) and IsTModule(arg.func.value.value.value.id, self.Trans.SymbolTable): + elif (isinstance(arg.func.value, ast.Attribute) and arg.func.value.attr == 'llvm' + and isinstance(arg.func.value.value, ast.Name) and arg.func.value.value.id == 'attr'): llvm_attr_name = arg.func.attr if llvm_attr_name in self._LLVM_ATTR_NAMES: fn_attrs[f'llvm.{llvm_attr_name}'] = True elif isinstance(arg, ast.Attribute): - if isinstance(arg.value, ast.Attribute) and isinstance(arg.value.value, ast.Name) and IsTModule(arg.value.value.id, self.Trans.SymbolTable) and arg.value.attr == 'attr': + if isinstance(arg.value, ast.Name) and arg.value.id == 'attr': attr_name = arg.attr if attr_name in ('noreturn', 'always_inline', 'noinline', 'cold', 'hot', 'constructor', 'destructor', 'pure', 'const', 'malloc', 'returns_nonnull', 'used', 'naked', 'no_instrument_function', 'warn_unused_result', 'weak', 'fallthrough', 'packed'): fn_attrs[attr_name] = True - elif isinstance(arg.value, ast.Attribute) and arg.value.attr == 'llvm' and isinstance(arg.value.value, ast.Attribute) and arg.value.value.attr == 'attr' and isinstance(arg.value.value.value, ast.Name) and IsTModule(arg.value.value.value.id, self.Trans.SymbolTable): + elif (isinstance(arg.value, ast.Attribute) and arg.value.attr == 'llvm' + and isinstance(arg.value.value, ast.Name) and arg.value.value.id == 'attr'): llvm_attr_name = arg.attr if llvm_attr_name in self._LLVM_ATTR_NAMES: fn_attrs[f'llvm.{llvm_attr_name}'] = True - # 检查 @t.TLS 装饰器(一次性初始化标记) + # 检查 @TLS 装饰器(一次性初始化标记) is_tls_func: bool = False if Node.decorator_list: for decorator in Node.decorator_list: if isinstance(decorator, ast.Attribute) and isinstance(decorator.value, ast.Name): - if IsTModule(decorator.value.id, _symtab) and decorator.attr == 'TLS': + if decorator.attr == 'TLS': is_tls_func = True break - elif isinstance(decorator, ast.Name) and decorator.id == 'TLS' and hasattr(t, 'TLS'): + elif isinstance(decorator, ast.Name) and decorator.id == 'TLS' and hasattr(TypeSystem, 'TLS'): is_tls_func = True break if Node.returns: @@ -1488,7 +1476,7 @@ class FunctionHandle(BaseHandle): try: rt_info = CTypeInfo.FromNode(Node.returns, self.Trans.SymbolTable) # 仅指针层数 <=1 才算裸 str/bytes(i8*)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), # 不能压平,否则返回类型错误。 if rt_info and rt_info.IsStr and rt_info.PtrCount <= 1: is_str_return = True @@ -1498,19 +1486,19 @@ class FunctionHandle(BaseHandle): if is_str_return: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CChar() + ReturnTypeInfo.BaseType = TypeSystem.CChar() ReturnTypeInfo.PtrCount = 1 elif Node.returns: if MultiRetTypes: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() else: try: if isinstance(Node.returns, ast.BinOp) and isinstance(Node.returns.op, ast.BitOr): ReturnTypeInfo = getattr(self.Trans, 'TypeMergeHandler', None) and self.Trans.TypeMergeHandler.MergeTypes(Node.returns) if not isinstance(ReturnTypeInfo, CTypeInfo): ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() if ((ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState) or (ReturnTypeInfo.PtrCount >= 2 and ReturnTypeInfo.BaseType is None)): def _FindNonVoidCTypeInfo(node): @@ -1537,9 +1525,9 @@ class FunctionHandle(BaseHandle): ReturnTypeInfo = found if ReturnTypeInfo.IsVoid and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() - # define 宏函数(返回注解含 t.CDefine,如 `int | t.CDefine`): - # 标记为编译期内联宏(alwaysinline),对齐裸 `-> t.CDefine` 路径 + ReturnTypeInfo.BaseType = TypeSystem.CInt() + # define 宏函数(返回注解含 CDefine,如 `int | CDefine`): + # 标记为编译期内联宏(alwaysinline),对齐裸 `-> CDefine` 路径 if AnnotationContainsName(Node.returns, 'CDefine'): if not hasattr(self, '_cdefine_funcs'): self._cdefine_funcs = set() @@ -1549,7 +1537,7 @@ class FunctionHandle(BaseHandle): if isinstance(Node.returns, ast.Name) and Node.returns.id in ('str', 'bytes'): is_str_type = True # 与 _GetFunctionSignatureLlvm 同口径:指针下标返回注解 - # (rawptr[T] / t.CPtr[T])走 ResolveAnnotationType 的 + # (rawptr[T] / CPtr[T])走 ResolveAnnotationType 的 # TypeMerge 通用解析,避免内层跨模块类退化为 i8*。 ReturnTypeInfo = self.ResolveAnnotationType(Node.returns) if ReturnTypeInfo and ReturnTypeInfo.IsDefine: @@ -1559,24 +1547,24 @@ class FunctionHandle(BaseHandle): ReturnTypeInfo.PtrCount = 1 if inferred[1] else 0 else: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() if not hasattr(self, '_cdefine_funcs'): self._cdefine_funcs = set() self._cdefine_funcs.add(FuncName) elif ReturnTypeInfo and ReturnTypeInfo.IsState: - pass # t.State is a modifier, preserve the actual return type + pass # State is a modifier, preserve the actual return type if ReturnTypeInfo is None: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CVoid() + ReturnTypeInfo.BaseType = TypeSystem.CVoid() # 仅指针层数 <=1 才算裸 str/bytes(i8*)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 if is_str_type or (ReturnTypeInfo.IsStr and ReturnTypeInfo.PtrCount <= 1): ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CChar() + ReturnTypeInfo.BaseType = TypeSystem.CChar() ReturnTypeInfo.PtrCount = 1 # 检查泛型类返回类型 (如 list[str]) # 注意:_from_node_subscript 对未识别的泛型下标(如 list[str])返回空 CTypeInfo(BaseType=None), - # 此时 IsVoid 为 False(因为 IsVoid 仅检查 t.CVoid 实例),需额外检测 BaseType is None + # 此时 IsVoid 为 False(因为 IsVoid 仅检查 CVoid 实例),需额外检测 BaseType is None if (isinstance(Node.returns, ast.Subscript) and isinstance(Node.returns.value, ast.Name) and hasattr(self.Trans.ClassHandler, '_generic_class_templates') @@ -1609,17 +1597,17 @@ class FunctionHandle(BaseHandle): ret_class, ret_type_args, Gen, type_names=ret_type_names, declare_only=True) if spec_name2 and spec_name2 in Gen.structs: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CStruct(name=spec_name2) + ReturnTypeInfo.BaseType = TypeSystem.CStruct(name=spec_name2) ReturnTypeInfo.PtrCount = 1 if (ReturnTypeInfo.IsVoid or ReturnTypeInfo.BaseType is None) and ReturnTypeInfo.PtrCount == 0 and not ReturnTypeInfo.IsState: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() except Exception: # 回退:设置默认返回类型为 CInt ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() else: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() inferred = self._infer_return_type_from_body(Node, Gen, ClassName) if inferred: ReturnTypeInfo = CTypeInfo.FromTypeName(inferred[0]) @@ -1650,20 +1638,20 @@ class FunctionHandle(BaseHandle): ParamTypeInfo = self.ResolveParamAnnotation(Arg.annotation) if ParamTypeInfo is None: ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CInt() + ParamTypeInfo.BaseType = TypeSystem.CInt() IsPtr = ParamTypeInfo.IsPtr if ParamTypeInfo and getattr(ParamTypeInfo, 'IsCpythonObject', False) and not IsPtr: IsPtr = True ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1) # 仅当指针层数 <=1 时才压平为 i8*(裸 str/bytes)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), # 不能压平,否则形参类型错误导致 _adjust_args 多 load 一层崩溃。 if (ParamTypeInfo.IsStr and ParamTypeInfo.PtrCount <= 1) or (isinstance(Arg.annotation, ast.Name) and Arg.annotation.id in ('str', 'bytes')): ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CChar() + ParamTypeInfo.BaseType = TypeSystem.CChar() ParamTypeInfo.PtrCount = 1 IsPtr = True - # C 语言中数组参数退化为指针:t.CArray[type, N] → type* + # C 语言中数组参数退化为指针:CArray[type, N] → type* if ParamTypeInfo.ArrayDims: ParamTypeInfo.ArrayDims = [] ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1) @@ -1674,7 +1662,7 @@ class FunctionHandle(BaseHandle): AnnStr: str = ast.unparse(Arg.annotation) if hasattr(ast, 'unparse') else str(Arg.annotation) raise SyntaxError( f"无法识别的参数类型注解: '{AnnStr}'(在函数 '{Node.name}' 的参数 '{Arg.arg}' 上)。" - f"请使用有效的 VPC 类型(如 t.CPtr、ast.AST 或已注册的结构体)。" + f"请使用有效的 VPC 类型(如 CPtr、ast.AST 或已注册的结构体)。" ) if ParamTypeInfo and ParamTypeInfo.IsFuncPtr: ParamType = ir.IntType(8).as_pointer() @@ -1684,15 +1672,15 @@ class FunctionHandle(BaseHandle): except Exception: # 回退:参数类型解析失败时使用默认 i32 ParamType = ir.IntType(32) ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CInt() + ParamTypeInfo.BaseType = TypeSystem.CInt() else: ParamType = ir.IntType(32) ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CInt() + ParamTypeInfo.BaseType = TypeSystem.CInt() ParamTypes.append(ParamType) ParamNames.append(Arg.arg) ParamTypeStrs.append(ParamTypeInfo) - # 自动取址模式(由注解读出):'ref' = &T、'temp' = &temp T、'always' = t.CAutoPtr + # 自动取址模式(由注解读出):'ref' = &T、'temp' = &temp T、'always' = CAutoPtr auto_mode_emit: str | None = FindAutoAddrMode(Arg.annotation) auto_addr_modes_emit.append(auto_mode_emit) Gen._record_var_signedness(Arg.arg, ParamIsUnsigned) @@ -1712,14 +1700,14 @@ class FunctionHandle(BaseHandle): for i, ReturnTypeNode in enumerate(MultiRetTypes): ReturnTypeInfo = CTypeInfo.FromNode(ReturnTypeNode, self.Trans.SymbolTable) # 仅指针层数 <=1 才算裸 str/bytes(i8*)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 if ReturnTypeInfo and ReturnTypeInfo.IsStr and ReturnTypeInfo.PtrCount <= 1: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CChar() + ReturnTypeInfo.BaseType = TypeSystem.CChar() ReturnTypeInfo.PtrCount = 1 if ReturnTypeInfo is None: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() RetType = Gen._ctype_to_llvm(ReturnTypeInfo) MultiRetLlvmTypes.append(RetType) ReturnType = ir.LiteralStructType(MultiRetLlvmTypes) @@ -1762,12 +1750,12 @@ class FunctionHandle(BaseHandle): try: RetTypeInfo = None RetTypeInfo = self.ResolveAnnotationType(Node.returns) - if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CInline): + if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, TypeSystem.CInline): IsInlineFunc = True - if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExport) and not RetTypeInfo.IsState: + if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, TypeSystem.CExport) and not RetTypeInfo.IsState: Gen._export_funcs.add(FuncName) IsUserMarkedExport = True - if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, t.CExtern): + if isinstance(RetTypeInfo, CTypeInfo) and RetTypeInfo.Storage and isinstance(RetTypeInfo.Storage, TypeSystem.CExtern): IsExternFunc = True Gen._export_funcs.add(FuncName) IsUserMarkedExport = True @@ -1778,7 +1766,7 @@ class FunctionHandle(BaseHandle): except Exception as _e: if _config_mode == "strict": self.Trans.LogWarning(f"异常被忽略: {_e}") - # 装饰器形式的存储类标记(@t.CExport / @t.CExtern / @t.CStatic / @t.State / @t.CInline) + # 装饰器形式的存储类标记(@CExport / @CExtern / @CStatic / @State / @CInline) deco_flags: dict[str, bool] = self._extract_decorator_storage_flags(Node) if deco_flags['is_inline']: IsInlineFunc = True @@ -1955,7 +1943,7 @@ class FunctionHandle(BaseHandle): saved_var_struct_class = dict(Gen.var_struct_class) if Gen.var_struct_class else {} saved_global_struct_class = dict(Gen.global_struct_class) if getattr(Gen, 'global_struct_class', None) else {} # 函数内部定义的变量会在赋值时添加到 var_type_info 中 - # 这样函数内部定义的元类型变量(如 a = t.CInt32T)就能被正确处理 + # 这样函数内部定义的元类型变量(如 a = CInt32T)就能被正确处理 for stmt in Node.body: if isinstance(stmt, ast.Global): self.Trans.ForHandler._RegisterGlobalNames(stmt.names, Gen) @@ -1989,7 +1977,7 @@ class FunctionHandle(BaseHandle): var = Gen._allocaEntry(param.type, name=param_name) Gen._store(param, var) Gen.variables[param_name] = var - # 为联合类型注解(如 Function | t.CPtr)的参数设置 var_struct_class, + # 为联合类型注解(如 Function | CPtr)的参数设置 var_struct_class, # 确保编译器能正确生成 GEP 访问结构体成员(如 func.Blocks、func.Params) for i, arg in enumerate(Node.args.args): if arg.annotation and isinstance(arg.annotation, ast.BinOp) and isinstance(arg.annotation.op, ast.BitOr): @@ -1997,13 +1985,13 @@ class FunctionHandle(BaseHandle): if param_name in Gen.variables: # 若 L1650-1657 已根据 param.type.pointee 匹配到正确的特化名 # (如 ndarray[double]),不覆盖:FindStructNameInAnnotation 对 - # 泛型注解 ndarray[t.CDouble] 会构造 ndarray[CDouble](与实际 + # 泛型注解 ndarray[CDouble] 会构造 ndarray[CDouble](与实际 # ndarray[double] 不匹配),回退到裸模板类名 ndarray(opaque), # 导致方法调用查找 ndarray.sum 而非 ndarray[double].sum。 if param_name in Gen.var_struct_class: _existing_ps: str = Gen.var_struct_class[param_name] # 指针占位名(rawptr / {sha1}.rawptr / rawptr[...])是模块限定 - # struct 联合(llvmlite.Function | t.CPtr)被 resolver 退化 + # struct 联合(llvmlite.Function | CPtr)被 resolver 退化 # 的产物,必须允许 FindStructNameInAnnotation 短名修正 # (否则 func.IsVarArg → "属性在类 'rawptr' 中找不到")。 if not (_existing_ps == 'rawptr' or '.rawptr' in _existing_ps @@ -2013,7 +2001,7 @@ class FunctionHandle(BaseHandle): arg.annotation, self.Trans, Gen) if found_struct: Gen.var_struct_class[param_name] = found_struct - # 普通类注解形参(非 BinOp 联合):rawptr[X] / t.CPtr[X] / X / t.X + # 普通类注解形参(非 BinOp 联合):rawptr[X] / CPtr[X] / X / X # 一律按"声明类"登记 var_struct_class。避免按 param.type.pointee 匹配 # 到泛型父特化(如 class Function(GSListNode[Function]) 的形参 func 被 # 登记成 GSListNode[Function],其 struct 仅含 Next → func.Blocks 访问 @@ -2092,7 +2080,7 @@ class FunctionHandle(BaseHandle): # 用 _direct_values 注册,Name 解析时直接返回 va_list 指针(i8*), # 不走 variables 的 load 路径(否则会把 i8* 当 char* 加载一个字节) Gen._direct_values[vararg_name] = va_list_ptr - # @t.TLS 一次性初始化检查:首次调用执行函数体,后续调用直接返回 + # @TLS 一次性初始化检查:首次调用执行函数体,后续调用直接返回 if is_tls_func: flag_name: str = f"__tls_init_done_{FuncName}" flag_global = None @@ -2190,13 +2178,13 @@ class FunctionHandle(BaseHandle): # - 末句是控制流(If/Match/While/For/Try/With)→ 掉出合法(隐式返回 # 规则:末句控制流 → unreachable;match/if 合成 after 块机械掉出, # 所有 arm 已 terminated 属正常) - # - 末句是普通语句 → 真掉出末尾;-> None / -> t.CVoid 视为 Void 合法, + # - 末句是普通语句 → 真掉出末尾;-> None / -> CVoid 视为 Void 合法, # 无注解 → C 风格过程(ConstZero,保持现状);其余注解报错 _last_stmt = Node.body[-1] if Node.body else None _is_ret_or_ctrl_tail: bool = isinstance(_last_stmt, ( ast.Return, ast.If, ast.Match, ast.While, ast.For, ast.Try, ast.With)) if Node.returns is not None and not _is_ret_or_ctrl_tail: - # void(None / t.CVoid,含 | 联合)/ extern|export 声明型辅助符号 + # void(None / CVoid,含 | 联合)/ extern|export 声明型辅助符号 # (State / CExport / CExtern)→ 掉出合法,不 fail-fast if not _IsVoidOrDeclAnnotation(Node.returns): raise Exception( diff --git a/lib/core/Handles/HandlesIf.py b/lib/core/Handles/HandlesIf.py index 2e92297..bd4ba7c 100644 --- a/lib/core/Handles/HandlesIf.py +++ b/lib/core/Handles/HandlesIf.py @@ -23,16 +23,21 @@ class IfHandle(BaseHandle): return None def _is_cif_call(self, node: ast.expr) -> bool: - """判定 If.test 是否为 cif/celif 的内部标记调用(c.@CIf 族,解析期合成)。 + """判定 If.test 是否为 cif/celif 的内部标记调用(@CIf 族,解析期合成)。 - 标记属性名带前导 '@'(词法器不可产出),故用户写的 c.CIf(...) 不会命中。 + 标记名带前导 '@'(词法器不可产出),故用户写的 CIf(...) 不会命中。 """ if isinstance(node, ast.Call): - if isinstance(node.func, ast.Attribute): - if isinstance(node.func.value, ast.Name) and node.func.value.id == 'c': - return node.func.attr in ('@CIf', '@CIfdef', '@CIfndef') if isinstance(node.func, ast.Name): return node.func.id in ('@CIf', '@CIfdef', '@CIfndef') + if (isinstance(node.func, ast.Attribute) + and isinstance(node.func.value, ast.Name) + and node.func.value.id == 'c' + and node.func.attr in ('CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif')): + from lib.core.LLVMCG.FuncGen import FailFastError + raise FailFastError( + f"`c.{node.func.attr}` 不是内建标记:cif/celif 条件请使用 " + f"`cif` / `celif` 语句与 `defined(NAME)` 谓词") return False def _resolve_macro_name(self, arg: ast.expr) -> str | None: diff --git a/lib/core/Handles/HandlesImports.py b/lib/core/Handles/HandlesImports.py index 64d0176..e9b1f6b 100644 --- a/lib/core/Handles/HandlesImports.py +++ b/lib/core/Handles/HandlesImports.py @@ -12,15 +12,15 @@ import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode -from lib.includes import t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry from lib.core.SymbolUtils import ParseListAnnotation, ExtractTypeNameFromBinOp, AnnotationContainsName, FindStructNameInAnnotationWithContext, FindAutoAddrMode from lib.core.SymbolUtils import EnumClassIntWidth, ExpandSoftKeywords from lib.core.SymbolUtils import ClassHasFuncLevelCVTable, IsVtableSlotMethod # 注解里的存储类 / 限定符标记:这些名字**不是类名**(联合注解里与指针类混写, -# 如 `t.CExtern | rawptr[CompilerFactory]`),提取"指针指向的类"时必须滤掉。 +# 如 `CExtern | rawptr[CompilerFactory]`),提取"指针指向的类"时必须滤掉。 _MARKER_ANNOT_NAMES: frozenset[str] = frozenset({ 'CExtern', 'CExport', 'CStatic', 'CInline', 'CConst', 'CVolatile', 'CRegister', 'CAuto', 'CDefine', 'CTypedef', 'CPostdefinition', 'CPtr', 'CArrayPtr', 'CVoid', @@ -99,7 +99,7 @@ def _HasRealParentClass(Node: ast.ClassDef) -> bool: def _VtableByClassLevelForImport(Node: ast.ClassDef, Gen: object) -> bool: """跨模块导入类的 VtableByClassLevel(忽略方法级 CVTable 标记的 vtable 状态)。 - 与 HandlesClassDef._resolve_class_flags 的口径一致:类级 @t.CVTable 或 + 与 HandlesClassDef._resolve_class_flags 的口径一致:类级 @CVTable 或 "有真实父类且父类不是 NoVTable" ⇒ True。供 SymbolUtils.IsVtableSlotMethod 判定方法是否占虚表槽(唯一的判据源),使导入侧的虚表槽序与定义模块逐槽相同。 """ @@ -472,14 +472,11 @@ class ImportHandle(BaseHandle): self.Trans._ImportedModules = set() for alias in Node.names: name = alias.name - if name in ('c', 't'): - if alias.asname: - self.Trans.SymbolTable.import_aliases[alias.asname] = name - AliasInfo = CTypeInfo() - AliasInfo.IsModuleAlias = True - AliasInfo.ResolvedModule = name - self.Trans.SymbolTable.insert(alias.asname, AliasInfo) - continue + # 内建标记按裸名书写(CPtr / CInt / CDefine ...),不再有 t / c 模块。 + if name in ('t', 'c'): + raise TypeError( + f"不支持 `import {name}`:请直接使用内建裸名标记" + f"(如 CPtr、CInt、CDefine、Asm)") self.Trans._ImportedModules.add(name) if alias.asname: self.Trans.SymbolTable.import_aliases[alias.asname] = name @@ -529,9 +526,9 @@ class ImportHandle(BaseHandle): if name not in _dt_map: _dt_map[name] = all_dt[name] continue - if not hasattr(self.Trans, '_t_c_imported_names'): - self.Trans._t_c_imported_names = {} - self.Trans._t_c_imported_names[asname] = (module, name) + if not hasattr(self.Trans, '_from_import_aliases'): + self.Trans._from_import_aliases = {} + self.Trans._from_import_aliases[asname] = (module, name) if name in Gen.functions: Gen.functions[asname] = Gen.functions[name] if name in Gen.structs: @@ -567,24 +564,11 @@ class ImportHandle(BaseHandle): def _EmitImportFromDeclarationsLlvm(self, Node: ast.ImportFrom, Gen: LlvmGeneratorMixin) -> None: module = Node.module if Node.module else '' - if module in ('c', 't'): - if not getattr(self.Trans, '_ImportedModules', None): - self.Trans._ImportedModules = set() - self.Trans._ImportedModules.add(module) - if not hasattr(self.Trans, '_t_c_imported_names'): - self.Trans._t_c_imported_names = {} - # 注册 t/c 类型别名到 _t_type_symbols(CType 子类) - t_type_syms = self.Trans.SymbolTable._t_type_symbols - for alias in Node.names: - name = alias.name - asname = alias.asname or name - self.Trans._t_c_imported_names[asname] = (module, name) - # 仅注册 CType 子类(CEnum/CUnion/CStruct/REnum 等) - if module == 't': - cls = getattr(t, name, None) - if isinstance(cls, type) and issubclass(cls, t.CType): - t_type_syms[asname] = cls - return + # 内建标记按裸名书写,不存在可导入的 t / c 模块。 + if module in ('t', 'c'): + raise TypeError( + f"不支持 `from {module} import ...`:请直接使用内建裸名标记" + f"(如 CPtr、CInt、CDefine、Asm)") if not getattr(self.Trans, '_ImportedModules', None): self.Trans._ImportedModules = set() current_module = self._get_current_module_name() @@ -1271,8 +1255,8 @@ class ImportHandle(BaseHandle): def _AnnotationStructName(self, annotation: ast.AST) -> str | None: """从注解里提取「指针指向的类」短名(递归,0 判定返回 None) - 覆盖形态:`X` / `mod.X` / `rawptr[X]` / `t.CPtr[X]` / 联合 `A | B`(两翼都试)。 - 存储类与限定符标记(`t.CExtern` / `t.CExport` / `t.CPtr` 等)不算类名, + 覆盖形态:`X` / `mod.X` / `rawptr[X]` / `CPtr[X]` / 联合 `A | B`(两翼都试)。 + 存储类与限定符标记(`CExtern` / `CExport` / `CPtr` 等)不算类名, 由 `_MARKER_ANNOT_NAMES` 过滤;返回的是**短名**,调用方再解析成 `Gen.structs` 真实键。 """ @@ -1301,9 +1285,7 @@ class ImportHandle(BaseHandle): return None return annotation.id if isinstance(annotation, ast.Attribute): - # `mod.Class`:mod 为 t/c 时是内建标记/内建类型名,不作为类的键 - if isinstance(annotation.value, ast.Name) and annotation.value.id in ('t', 'c'): - return None + # `mod.Class`:属性名是内建标记/内建类型名时,不作为类的键 if annotation.attr in _MARKER_ANNOT_NAMES: return None return annotation.attr @@ -1339,7 +1321,7 @@ class ImportHandle(BaseHandle): is_string_val = False TypeInfo = None # 【跨模块模块级变量的**类登记**】`CTypeInfo.FromNode` 对 - # `X | t.CPtr` / `rawptr[X]` 注解只给出指针占位(rawptr[X] 折叠成 i8*), + # `X | CPtr` / `rawptr[X]` 注解只给出指针占位(rawptr[X] 折叠成 i8*), # 且本函数**只算类型、不登记变量类** → 消费侧 `Mod.Var.Field` 链在 # `_get_var_class` 里解析为空:StructGenMixin.vp:139 "属性访问未能解析出 # 目标类型/成员"、CallGenLeafKit.vp:589 / ClassGenVTable.vp:99 误报 @@ -1365,7 +1347,7 @@ class ImportHandle(BaseHandle): if Node.annotation: parse_result = ParseListAnnotation(Node.annotation) if parse_result and not parse_result.is_pointer: - # t.CArray[type, count] 数组声明 + # CArray[type, count] 数组声明 elem_type_node = parse_result.elem_type_node count_node = parse_result.count_node ElemTypeInfo = CTypeInfo.FromNode(elem_type_node, self.Trans.SymbolTable) @@ -1408,17 +1390,11 @@ class ImportHandle(BaseHandle): # 检查是否是 CDefine 常量或 CTypedef 类型别名 IsCDefine = False IsCTypedef = False - if Node.annotation: - if isinstance(Node.annotation, ast.Attribute): - if getattr(Node.annotation.value, 'id', None) == 't' and Node.annotation.attr == 'CDefine': - IsCDefine = True - elif getattr(Node.annotation.value, 'id', None) == 't' and Node.annotation.attr == 'CTypedef': - IsCTypedef = True - elif isinstance(Node.annotation, ast.Name): - if Node.annotation.id == 'CDefine': - IsCDefine = True - elif Node.annotation.id == 'CTypedef': - IsCTypedef = True + if isinstance(Node.annotation, ast.Name): + if Node.annotation.id == 'CDefine': + IsCDefine = True + elif Node.annotation.id == 'CTypedef': + IsCTypedef = True if IsCTypedef: # 检查符号是否已存在且已正确解析(OriginalType 已设置),避免覆盖 @@ -1432,13 +1408,13 @@ class ImportHandle(BaseHandle): else: ValueTypeInfo = self.Trans.TypeMergeHandler.GetCTypeInfo(Node.value) if isinstance(ValueTypeInfo, CTypeInfo) and (ValueTypeInfo.BaseType or ValueTypeInfo.PtrCount > 0): - # GetCTypeInfo 对 t.CInt 等 Attribute 返回的 BaseType 可能是 CType 基类实例 + # GetCTypeInfo 对 CInt 等 Attribute 返回的 BaseType 可能是 CType 基类实例 # (而非具体子类如 CInt),导致 _resolve_typedef_int_width 无法解析位宽。 # 此时从 Node.value 提取类型名,设置 OriginalType 为字符串, # 让 _resolve_typedef_int_width 通过 CTypeRegistry.GetClassByName 解析。 - if ValueTypeInfo.BaseType and type(ValueTypeInfo.BaseType) is t.CType: - if isinstance(Node.value, ast.Attribute) and getattr(Node.value.value, 'id', None) == 't': - type_name: str = Node.value.attr + if ValueTypeInfo.BaseType and type(ValueTypeInfo.BaseType) is TypeSystem.CType: + if isinstance(Node.value, ast.Name): + type_name: str = Node.value.id resolved_cls = CTypeRegistry.GetClassByName(type_name) if resolved_cls is not None: ValueTypeInfo.OriginalType = type_name @@ -1488,7 +1464,7 @@ class ImportHandle(BaseHandle): self._RegisterCDefineSymbol(FullName, DefineValue, Node.lineno, ModulePath or 'unknown') return # 不再继续生成 LLVM 全局变量 - # t.State 标记的全局变量:只声明不定义(external linkage),避免 DSO/non-DSO 重定义 + # State 标记的全局变量:只声明不定义(external linkage),避免 DSO/non-DSO 重定义 if TypeInfo and TypeInfo.IsState: if VarName not in Gen.module.globals: gv = ir.GlobalVariable(Gen.module, var_type, name=VarName) @@ -1612,22 +1588,13 @@ class ImportHandle(BaseHandle): if info.IsDefine and info.DefineValue is not None: return info.DefineValue elif isinstance(value_node, ast.Call): - if isinstance(value_node.func, ast.Attribute): - if getattr(value_node.func.value, 'id', None) == 't': - if value_node.args: - return self._ExtractConstValue(value_node.args[0]) - elif isinstance(value_node.func, ast.Name): + if isinstance(value_node.func, ast.Name): if value_node.args: return self._ExtractConstValue(value_node.args[0]) return None def _ExtractTypedefOriginalType(self, value_node: ast.AST) -> str | None: - if isinstance(value_node, ast.Attribute): - if getattr(value_node.value, 'id', None) == 't': - llvm_str = CTypeRegistry.NameToLLVM(value_node.attr) - if llvm_str: - return llvm_str - elif isinstance(value_node, ast.Name): + if isinstance(value_node, ast.Name): llvm_str = CTypeRegistry.NameToLLVM(value_node.id) if llvm_str: return llvm_str @@ -1642,12 +1609,7 @@ class ImportHandle(BaseHandle): if parts: return '|'.join(parts) elif isinstance(value_node, ast.Call): - if isinstance(value_node.func, ast.Attribute): - if getattr(value_node.func.value, 'id', None) == 't': - llvm_str = CTypeRegistry.NameToLLVM(value_node.func.attr) - if llvm_str: - return llvm_str - elif isinstance(value_node.func, ast.Name): + if isinstance(value_node.func, ast.Name): llvm_str = CTypeRegistry.NameToLLVM(value_node.func.id) if llvm_str: return llvm_str @@ -1656,7 +1618,7 @@ class ImportHandle(BaseHandle): def _RegisterCDefineSymbol(self, FullName: str, DefineValue: object, lineno: int, FilePath: str) -> None: """Register CDefine constant to SymbolTable""" # 防御:新值为 None 但已存在非 None 值时保留旧值。 - # 翻译期间声明发射调用 _ExtractConstValue(不支持 ast.Attribute 形式如 t.CSizeT().Size), + # 翻译期间声明发射调用 _ExtractConstValue(不支持 ast.Attribute 形式如 CSizeT().Size), # 会返回 None 并覆盖共享符号表中已由 ConstEvaluator 正确求值的值(如 8)。 # 共享符号表在 _build_shared_symbol_data 阶段已正确求值,此处不应覆盖。 if DefineValue is None: @@ -1677,7 +1639,7 @@ class ImportHandle(BaseHandle): AnnotationContainsName(annotation, 'State')) def _check_decorators_for_state(self, Node: ast.FunctionDef) -> bool: - """检查装饰器列表中是否包含 @t.CExport / @t.CExtern / @t.State(t.CExport 既能作返回值注解也能作装饰器)""" + """检查装饰器列表中是否包含 @CExport / @CExtern / @State(CExport 既能作返回值注解也能作装饰器)""" if not Node.decorator_list: return False for decorator in Node.decorator_list: @@ -1690,8 +1652,8 @@ class ImportHandle(BaseHandle): def _EmitExternalFuncDeclLlvm(self, Node: ast.FunctionDef, Gen: LlvmGeneratorMixin, is_class_method: bool = False, source_module_name: str | None = None, register_module_name: str | None = None, reexport_module_names: list[str] | None = None) -> None: FuncName = Node.name if (Node.returns and self._check_annotation_for_state(Node.returns)) or self._check_decorators_for_state(Node): - Gen._export_funcs.add(FuncName) # t.State 标记的外部 C 函数必须保持原始名称,以便链接器解析 - if source_module_name and source_module_name not in ('c', 't'): + Gen._export_funcs.add(FuncName) # State 标记的外部 C 函数必须保持原始名称,以便链接器解析 + if source_module_name: _src_sha1 = Gen.ModuleSha1Map.get(source_module_name) if not _src_sha1: _init_name = f"{source_module_name}.__init__" @@ -1719,10 +1681,10 @@ class ImportHandle(BaseHandle): if Node.decorator_list: for decorator in Node.decorator_list: if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute): - # fail-fast:`@c.CReturn` 已移除,扫到即报错。 + # fail-fast:`@CReturn` 已移除,扫到即报错。 if decorator.func.attr == 'CReturn': raise SyntaxError( - f"函数 '{FuncName}':`@c.CReturn` 已移除:请改用返回注解 " + f"函数 '{FuncName}':`@CReturn` 已移除:请改用返回注解 " f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)" ) IsPtr = False @@ -1731,14 +1693,14 @@ class ImportHandle(BaseHandle): try: ReturnTypeInfo = self.ResolveAnnotationType(Node.returns) # 仅指针层数 <=1 才算裸 str/bytes(i8*)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。 if ReturnTypeInfo and ReturnTypeInfo.IsStr and ReturnTypeInfo.PtrCount <= 1: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CChar() + ReturnTypeInfo.BaseType = TypeSystem.CChar() ReturnTypeInfo.PtrCount = 1 if ReturnTypeInfo is None: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() IsPtr = ReturnTypeInfo.IsPtr except RecursionError: # 家族口径(HandlesBase.py:1060-1068):RecursionError 是类型解析链成环的 @@ -1750,10 +1712,10 @@ class ImportHandle(BaseHandle): if not (isinstance(e, AttributeError) and "'NoneType'" in str(e)): _vlog().warning(f"HandlesImports: 忽略异常 {e}", exc_info=e) ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() else: ReturnTypeInfo = CTypeInfo() - ReturnTypeInfo.BaseType = t.CInt() + ReturnTypeInfo.BaseType = TypeSystem.CInt() ReturnType = Gen._ctype_to_llvm(ReturnTypeInfo) if (isinstance(ReturnType, ir.VoidType) or (isinstance(ReturnType, ir.PointerType) and isinstance(ReturnType.pointee, ir.VoidType))) and Node.returns: RetAnnName = None @@ -1772,7 +1734,7 @@ class ImportHandle(BaseHandle): elif IsPtr or RetAnnName: ReturnType = ir.PointerType(ir.IntType(8)) # __new__ 方法应返回类指针类型(堆分配替换),与 _GetFunctionSignatureLlvm/_EmitFunctionLlvm 保持一致 - # .pyi 生成器对无返回类型注解的 __new__ 默认使用 t.CInt,这里修正为 ClassName* + # .pyi 生成器对无返回类型注解的 __new__ 默认使用 CInt,这里修正为 ClassName* if '.__new__' in FuncName: _np = FuncName.split('.') if len(_np[0]) == 16 and all(_c in '0123456789abcdef' for _c in _np[0]): @@ -1830,20 +1792,20 @@ class ImportHandle(BaseHandle): ParamTypeInfo = self.ResolveAnnotationType(Arg.annotation) if ParamTypeInfo is None: ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CInt() + ParamTypeInfo.BaseType = TypeSystem.CInt() ParamIsPtr = ParamTypeInfo.IsPtr if i == 0 and is_method and Arg.arg == 'self' and class_is_cpython: ParamIsPtr = True ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1) # 仅当指针层数 <=1 时才压平为 i8*(裸 str/bytes)。 - # `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), + # `str | CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组), # 不能压平,否则形参类型错误导致 _adjust_args 多 load 一层崩溃。 if (ParamTypeInfo.IsStr and ParamTypeInfo.PtrCount <= 1) or (isinstance(Arg.annotation, ast.Name) and Arg.annotation.id in ('str', 'bytes')): ParamTypeInfo = CTypeInfo() - ParamTypeInfo.BaseType = t.CChar() + ParamTypeInfo.BaseType = TypeSystem.CChar() ParamTypeInfo.PtrCount = 1 ParamIsPtr = True - # C 语言中数组参数退化为指针:t.CArray[type, N] → type* + # C 语言中数组参数退化为指针:CArray[type, N] → type* if ParamTypeInfo.ArrayDims: ParamTypeInfo.ArrayDims = [] ParamTypeInfo.PtrCount = max(ParamTypeInfo.PtrCount, 1) @@ -1877,10 +1839,10 @@ class ImportHandle(BaseHandle): _is_export = False if isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.IsState: _is_export = True - if isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.Storage and isinstance(ReturnTypeInfo.Storage, t.CExport) and not ReturnTypeInfo.IsState: + if isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.Storage and isinstance(ReturnTypeInfo.Storage, TypeSystem.CExport) and not ReturnTypeInfo.IsState: Gen._export_funcs.add(FuncName) _is_export = True - if isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.Storage and isinstance(ReturnTypeInfo.Storage, t.CExtern): + if isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.Storage and isinstance(ReturnTypeInfo.Storage, TypeSystem.CExtern): Gen._export_funcs.add(FuncName) _is_export = True if not _is_export: @@ -1931,7 +1893,7 @@ class ImportHandle(BaseHandle): if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE: existing.MetaList = func_meta # 同时注册带模块前缀的符号,以便 module.func_name 查找能命中 - if source_module_name and source_module_name not in ('c', 't'): + if source_module_name: FullSymKey = f"{source_module_name}.{FuncName}" if not self.Trans.SymbolTable.has(FullSymKey): FullFuncInfo = CTypeInfo() @@ -1999,28 +1961,19 @@ class ImportHandle(BaseHandle): break if not IsCenum and not IsRenum and getattr(Node, 'decorator_list', None): for decorator in Node.decorator_list: - if isinstance(decorator, ast.Attribute): - if getattr(decorator.value, 'id', None) == 't': - if decorator.attr == 'Object': - IsCpythonObject = True - elif decorator.attr == 'CVTable': - IsCVTable = True - elif decorator.attr == 'NoVTable': - IsNoVTable = True - elif decorator.attr == 'REnum': - IsRenum = True - elif decorator.attr == 'CEnum' or decorator.attr == 'Enum': - IsCenum = True + if isinstance(decorator, ast.Name): + if decorator.id == 'Object': + IsCpythonObject = True + elif decorator.id == 'CVTable': + IsCVTable = True + elif decorator.id == 'NoVTable': + IsNoVTable = True + elif decorator.id == 'REnum': + IsRenum = True + elif decorator.id == 'CEnum' or decorator.id == 'Enum': + IsCenum = True elif isinstance(decorator, ast.Call): - if isinstance(decorator.func, ast.Attribute): - if getattr(decorator.func.value, 'id', None) == 't': - if decorator.func.attr == 'Object': - IsCpythonObject = True - elif decorator.func.attr == 'CVTable': - IsCVTable = True - elif decorator.func.attr == 'NoVTable': - IsNoVTable = True - elif isinstance(decorator.func, ast.Name): + if isinstance(decorator.func, ast.Name): if decorator.func.id == 'Object': IsCpythonObject = True elif decorator.func.id == 'CVTable': @@ -2031,14 +1984,14 @@ class ImportHandle(BaseHandle): if getattr(Node, 'decorator_list', None): for decorator in Node.decorator_list: if isinstance(decorator, ast.Call): - if isinstance(decorator.func, ast.Attribute): - if getattr(decorator.func.value, 'id', None) == 'c' and decorator.func.attr == 'Attribute': - for arg in decorator.args: - if isinstance(arg, ast.Attribute): - if isinstance(arg.value, ast.Attribute): - if getattr(arg.value.value, 'id', None) == 't' and arg.value.attr == 'attr' and arg.attr == 'packed': - IsPacked = True - # 方法级 virtual(`virtual def m(...)` ⇒ 方法装饰器 @t.CVTable)触发类级 vtable: + if isinstance(decorator.func, ast.Name) and decorator.func.id == 'Attribute': + for arg in decorator.args: + if (isinstance(arg, ast.Attribute) + and isinstance(arg.value, ast.Name) + and arg.value.id == 'attr' + and arg.attr == 'packed'): + IsPacked = True + # 方法级 virtual(`virtual def m(...)` ⇒ 方法装饰器 @CVTable)触发类级 vtable: # 与 HandlesClassDef._resolve_class_flags / VPC _detect_vtable_status 的 # `_has_any_func_cvtable` 分支对齐(跨模块这里只能判"类级 NoVTable / # 无真实父类"两种可判定形态;父类 vtable 状态由 .pyi 按需注册路径解析)。 @@ -2088,7 +2041,7 @@ class ImportHandle(BaseHandle): if IsCenum: EnumTypeNode = CTypeInfo() EnumTypeNode.Name = ClassName - EnumTypeNode.BaseType = t.CEnum(ClassName) + EnumTypeNode.BaseType = TypeSystem.CEnum(ClassName) EnumTypeNode.IsEnum = True # [跨模块枚举宽度] 读侧重推导:.vpi/.pyi 保留成员注解(`Name: T`), # 故在本处按"最宽成员类型"重算(与定义端 HandlesClassDef 同一规则源 @@ -2123,7 +2076,7 @@ class ImportHandle(BaseHandle): next_enum_value += 1 MemberNode = CTypeInfo() MemberNode.Name = VarName - MemberNode.BaseType = t.CEnum(ClassName) + MemberNode.BaseType = TypeSystem.CEnum(ClassName) MemberNode.value = value MemberNode.EnumName = ClassName MemberNode.Lineno = item.lineno @@ -2141,7 +2094,7 @@ class ImportHandle(BaseHandle): RenumTypeNode.IsRenum = True RenumTypeNode.IsEnum = True # 兼容 IsEnum 检查 # REnum 在内存布局上是 struct,必须设置 IsStruct=True 才能让 - # HandlesTypeMerge 的 CPtr 吸收逻辑生效(REnumType | t.CPtr = REnumType*) + # HandlesTypeMerge 的 CPtr 吸收逻辑生效(REnumType | CPtr = REnumType*) RenumTypeNode.IsStruct = True if module_name: FullName = f"{module_name}.{ClassName}" @@ -2314,8 +2267,8 @@ class ImportHandle(BaseHandle): # 会被解析为 opaque struct,LLVM 报 "invalid type for function argument"。 # 字段(AnnAssign)仍正常加载,确保继承字段(如 GSListNode.Next)可被展平。 if not IsGenericClass: - # 虚表槽筛选:方法级 `novirtual def`(⇒ @t.NoVTable)不进槽、方法级 - # `virtual def`(⇒ @t.CVTable)进槽——判据为 SymbolUtils.IsVtableSlotMethod + # 虚表槽筛选:方法级 `novirtual def`(⇒ @NoVTable)不进槽、方法级 + # `virtual def`(⇒ @CVTable)进槽——判据为 SymbolUtils.IsVtableSlotMethod # (唯一规则源,与定义端 HandlesClassDef / VPC _should_method_be_virtual 同口径), # 保证跨模块虚表槽序与定义模块逐槽一致。 _VtByClassLevel: bool = _VtableByClassLevelForImport(Node, Gen) @@ -2404,7 +2357,7 @@ class ImportHandle(BaseHandle): if VarName not in {m[0] for m in Gen.class_members[ClassName]}: Gen.class_members[ClassName].append((VarName, MemberType)) Gen.class_member_bitfields[ClassName][VarName] = 0 - # 与 HandlesClassDef 对齐:联合类型字段(如 `list[str] | t.CPtr`) + # 与 HandlesClassDef 对齐:联合类型字段(如 `list[str] | CPtr`) # 记录泛型特化名到 class_member_element_class。否则跨模块 import # 的类(如 TypeGenBase.CTypedefNames)缺此记录,_HandleLenLlvm # 无法识别字段为 list → len() 误编译为 strlen → stdint 崩溃。 @@ -2468,7 +2421,7 @@ class ImportHandle(BaseHandle): else: # rawptr[裸结构](如 rawptr[Token]):跨模块 stub 会把自引用/类内 # 指针字段退化为 i8*,链式成员访问(a.b.c)需 element_class 恢复 - # struct 身份走 char*→struct cast。HEAD 态 `Token | t.CPtr` 联合 + # struct 身份走 char*→struct cast。HEAD 态 `Token | CPtr` 联合 # 由上方 BinOp 分支登记;rawptr 重构后此分支补齐(阻塞 A 根因)。 # 与 HandlesClassDef 的 rawptr 分支对称。 _slc_name_s: str | None = None @@ -2874,7 +2827,7 @@ class ImportHandle(BaseHandle): _mn: str = _m.split('.')[-1] if '.' in _m else _m _child_method_map[_mn] = _m # 从 .vpi 的 FunctionDef 补充子类方法映射(覆盖方法可能尚未注册)。 - # 方法级 `novirtual def`(⇒ @t.NoVTable)不占槽,**不得**用它覆盖父类槽位 + # 方法级 `novirtual def`(⇒ @NoVTable)不占槽,**不得**用它覆盖父类槽位 # ——与 VPC _collect_vtable_methods 的 child_nvt 分支同口径(子类标记 # NoVTable 时槽位仍指向实际定义类的实现)。 _VtByClassLevelC: bool = _VtableByClassLevelForImport(Node, Gen) @@ -3908,7 +3861,7 @@ class ImportHandle(BaseHandle): func_type = self._parse_llvm_declare(stripped, Gen) if func_type is not None: # __new__ 方法应返回类指针类型(堆分配替换),与 _GetFunctionSignatureLlvm/_EmitFunctionLlvm 保持一致 - # .stub.ll 由 .pyi 生成,.pyi 生成器对无返回类型注解的 __new__ 默认使用 t.CInt,这里修正为 ClassName* + # .stub.ll 由 .pyi 生成,.pyi 生成器对无返回类型注解的 __new__ 默认使用 CInt,这里修正为 ClassName* if '.__new__' in func_name: _np = func_name.split('.') if len(_np[0]) == 16 and all(_c in '0123456789abcdef' for _c in _np[0]): diff --git a/lib/core/Handles/HandlesMatch.py b/lib/core/Handles/HandlesMatch.py index 30d3484..17458f6 100644 --- a/lib/core/Handles/HandlesMatch.py +++ b/lib/core/Handles/HandlesMatch.py @@ -350,62 +350,59 @@ class MatchHandle(BaseHandle): if not HasDefault: Gen.builder.position_at_start(DefaultBB) Gen.builder.branch(AfterBB) - elif not any(isinstance(c.pattern, ast.MatchAs) and c.pattern.pattern is None for c in Node.cases) and not any(isinstance(c.pattern, ast.MatchSequence) for c in Node.cases): + elif not any(isinstance(pattern, ast.MatchAs) and c.pattern.pattern is None for c in Node.cases) and not any(isinstance(pattern, ast.MatchSequence) for c in Node.cases): Gen.builder.position_at_start(DefaultBB) Gen.builder.branch(AfterBB) Gen.builder.position_at_start(AfterBB) - @staticmethod - def _HasNoBreakMarker(Stmts: list[ast.stmt]) -> bool: - """case 体(含其嵌套 body/orelse)是否含 `fallthrough` 标记(c.NoBreak())""" - for stmt in Stmts: - if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Call): - if isinstance(stmt.value.func, ast.Attribute): - if (isinstance(stmt.value.func.value, ast.Name) and - stmt.value.func.value.id == 'c' and - stmt.value.func.attr == 'NoBreak'): - return True - NestedBody: Any = getattr(stmt, 'body', None) - if NestedBody and isinstance(NestedBody, list) and MatchHandle._HasNoBreakMarker(NestedBody): - return True - NestedElse: Any = getattr(stmt, 'orelse', None) - if NestedElse and isinstance(NestedElse, list) and MatchHandle._HasNoBreakMarker(NestedElse): - return True - return False - - def _HandleMatchCaseBody(self, Gen: "Translator.LlvmGen", - Body: list[ast.stmt], AfterBB: ir.Block, - IsSwitch: bool) -> None: - """翻译一个 case 体:case 体内的 break 目标是 AfterBB(C switch 语义) - - - case 内 break 跳出 **match/switch**(而非外层循环):翻译前把 AfterBB - 压入 loop_break_targets,翻译完弹出(外层循环目标不受影响)。 - - 同时把 Gen.in_switch_case 置为 IsSwitch(进出恢复):供 `fallthrough` - 标记语句判定合法性 —— 只有 switch 的 case 体内才允许,写进 match - (完全禁止 fallthrough)或 switch 之外由 HandlesBody fail-fast。 - """ - Targets: list = Gen.loop_break_targets - Targets.append(AfterBB) - PrevInSwitch: bool = Gen.in_switch_case - Gen.in_switch_case = IsSwitch - try: - self.HandleBodyLlvm(Body) - finally: - Gen.in_switch_case = PrevInSwitch - Targets.pop() - - @staticmethod - def _FallThroughTarget(CaseBBs: list[ir.Block], CaseIdx: int, AfterBB: ir.Block) -> ir.Block: - """fallthrough 的落点:下一个 case 的 body(无后继槽位时落到 AfterBB) - - `fallthrough`(vast 关键字,脱糖为 c.NoBreak())表示"本 case 不自动 - 跳出 switch",直接落到下一个 case 的 body(对齐 C 的 [[fallthrough]])。 - """ - NextIdx: int = CaseIdx + 1 - if 0 <= NextIdx < len(CaseBBs): - return CaseBBs[NextIdx] - return AfterBB - + @staticmethod + def _HasNoBreakMarker(Stmts: list[ast.stmt]) -> bool: + """case 体(含其嵌套 body/orelse)是否含 `fallthrough` 标记(NoBreak())""" + for stmt in Stmts: + if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Call): + if isinstance(stmt.value.func, ast.Name) and stmt.value.func.id == 'NoBreak': + return True + NestedBody: Any = getattr(stmt, 'body', None) + if NestedBody and isinstance(NestedBody, list) and MatchHandle._HasNoBreakMarker(NestedBody): + return True + NestedElse: Any = getattr(stmt, 'orelse', None) + if NestedElse and isinstance(NestedElse, list) and MatchHandle._HasNoBreakMarker(NestedElse): + return True + return False + + def _HandleMatchCaseBody(self, Gen: "Translator.LlvmGen", + Body: list[ast.stmt], AfterBB: ir.Block, + IsSwitch: bool) -> None: + """翻译一个 case 体:case 体内的 break 目标是 AfterBB(C switch 语义) + + - case 内 break 跳出 **match/switch**(而非外层循环):翻译前把 AfterBB + 压入 loop_break_targets,翻译完弹出(外层循环目标不受影响)。 + - 同时把 Gen.in_switch_case 置为 IsSwitch(进出恢复):供 `fallthrough` + 标记语句判定合法性 —— 只有 switch 的 case 体内才允许,写进 match + (完全禁止 fallthrough)或 switch 之外由 HandlesBody fail-fast。 + """ + Targets: list = Gen.loop_break_targets + Targets.append(AfterBB) + PrevInSwitch: bool = Gen.in_switch_case + Gen.in_switch_case = IsSwitch + try: + self.HandleBodyLlvm(Body) + finally: + Gen.in_switch_case = PrevInSwitch + Targets.pop() + + @staticmethod + def _FallThroughTarget(CaseBBs: list[ir.Block], CaseIdx: int, AfterBB: ir.Block) -> ir.Block: + """fallthrough 的落点:下一个 case 的 body(无后继槽位时落到 AfterBB) + + `fallthrough`(vast 关键字,脱糖为 NoBreak())表示"本 case 不自动 + 跳出 switch",直接落到下一个 case 的 body(对齐 C 的 [[fallthrough]])。 + """ + NextIdx: int = CaseIdx + 1 + if 0 <= NextIdx < len(CaseBBs): + return CaseBBs[NextIdx] + return AfterBB + def _HandleRenumMatchLlvm(self, Node: ast.Match, RenumName: str, SubjectPtr: ir.Value) -> None: Gen: "Translator.LlvmGen" = self.Trans.LlvmGen if isinstance(SubjectPtr.type, ir.PointerType) and isinstance(SubjectPtr.type.pointee, ir.PointerType): @@ -603,7 +600,7 @@ class MatchHandle(BaseHandle): if not HasDefault: Gen.builder.position_at_start(DefaultBB) Gen.builder.branch(AfterBB) - elif not any(isinstance(c.pattern, ast.MatchAs) and c.pattern.pattern is None for c in Node.cases) and not any(isinstance(c.pattern, ast.MatchSequence) for c in Node.cases): + elif not any(isinstance(pattern, ast.MatchAs) and c.pattern.pattern is None for c in Node.cases) and not any(isinstance(pattern, ast.MatchSequence) for c in Node.cases): Gen.builder.position_at_start(DefaultBB) Gen.builder.branch(AfterBB) Gen.builder.position_at_start(AfterBB) \ No newline at end of file diff --git a/lib/core/Handles/HandlesSpecialCall.py b/lib/core/Handles/HandlesSpecialCall.py index cbc40aa..56e1db9 100644 --- a/lib/core/Handles/HandlesSpecialCall.py +++ b/lib/core/Handles/HandlesSpecialCall.py @@ -6,8 +6,7 @@ if TYPE_CHECKING: from lib.core.translator import Translator from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin from lib.core.Handles.HandlesBase import BaseHandle -from lib.includes.t import CTypeRegistry -from lib.core.SymbolUtils import IsTModule +from lib.core.TypeSystem import CTypeRegistry from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode @@ -66,14 +65,14 @@ class CSpecialCallHandle(BaseHandle): var_ptr = Gen.variables[VarName] if isinstance(var_ptr.type, ir.PointerType): # For pointer-to-pointer allocas (var_ptr is T**): - # - If T is a named struct (@t.Object class), the variable semantically - # IS the struct, so c.Addr should return the struct pointer value. + # - If T is a named struct (@Object class), the variable semantically + # IS the struct, so Addr should return the struct pointer value. # - If T is a primitive pointer type (e.g., i8*), the variable semantically - # holds a pointer, so c.Addr should return &var (alloca address). + # holds a pointer, so Addr should return &var (alloca address). if isinstance(var_ptr.type.pointee, ir.PointerType): pointee = var_ptr.type.pointee.pointee if isinstance(pointee, ir.IdentifiedStructType): - # @t.Object class variable — return Loaded struct pointer + # @Object class variable — return Loaded struct pointer ArgVal = self.HandleExprLlvm(Arg) if ArgVal and isinstance(ArgVal.type, ir.PointerType): return Gen.builder.bitcast(ArgVal, ir.IntType(8).as_pointer(), name="addr_as_i8ptr") @@ -96,23 +95,22 @@ class CSpecialCallHandle(BaseHandle): target_arg: ast.expr = Node.args[0] value_arg: ast.expr = Node.args[1] target_ptr: ir.Value | None = None - if isinstance(target_arg, ast.Call) and isinstance(target_arg.func, ast.Attribute): - if isinstance(target_arg.func.value, ast.Name) and target_arg.func.value.id == 'c': - if target_arg.func.attr == 'Deref' and target_arg.args: - deref_arg = target_arg.args[0] - if isinstance(deref_arg, ast.Name) and deref_arg.id in Gen.variables and Gen.variables[deref_arg.id] is not None: - target_ptr = Gen._load(Gen.variables[deref_arg.id], name="deref_load_ptr") - else: - inner_value = self.HandleExprLlvm(deref_arg) - if inner_value: - if isinstance(inner_value.type, ir.PointerType): - if isinstance(inner_value.type.pointee, ir.PointerType): - inner_value = Gen._load(inner_value, name="cast_deref") - target_ptr = inner_value - elif target_arg.func.attr == 'Addr' and target_arg.args: - target_ptr = self.HandleExprLlvm(target_arg) - elif isinstance(target_arg.func.value, ast.Name) and IsTModule(target_arg.func.value.id, self.Trans.SymbolTable): - type_attr = target_arg.func.attr + if isinstance(target_arg, ast.Call) and isinstance(target_arg.func, ast.Name): + if target_arg.func.id == 'Deref' and target_arg.args: + deref_arg = target_arg.args[0] + if isinstance(deref_arg, ast.Name) and deref_arg.id in Gen.variables and Gen.variables[deref_arg.id] is not None: + target_ptr = Gen._load(Gen.variables[deref_arg.id], name="deref_load_ptr") + else: + inner_value = self.HandleExprLlvm(deref_arg) + if inner_value: + if isinstance(inner_value.type, ir.PointerType): + if isinstance(inner_value.type.pointee, ir.PointerType): + inner_value = Gen._load(inner_value, name="cast_deref") + target_ptr = inner_value + elif target_arg.func.id == 'Addr' and target_arg.args: + target_ptr = self.HandleExprLlvm(target_arg) + else: + type_attr = target_arg.func.id resolved_cname = self.Trans.TSpecialCallHandle._ResolveTAttrToCName(type_attr) if target_arg.args and resolved_cname is not None: inner_val = self.HandleExprLlvm(target_arg.args[0]) @@ -155,7 +153,7 @@ class CSpecialCallHandle(BaseHandle): def EmitRawCopyLlvm(self, DstPtr: ir.Value, SrcPtr: ir.Value, Gen: LlvmGeneratorMixin, NamePrefix: str = "rawcopy") -> bool: - """Emit `*dst = *src` as a raw byte copy (c.Load semantics); False if unusable. + """Emit `*dst = *src` as a raw byte copy (Load semantics); False if unusable. The width comes from the destination pointee and the source pointer is bitcast to it, so this reinterprets memory instead of converting values @@ -179,8 +177,8 @@ class CSpecialCallHandle(BaseHandle): Gen: LlvmGeneratorMixin = self.Trans.LlvmGen if len(Node.args) < 2: return ir.Constant(ir.IntType(32), 0) - # c.Load(a, b) 语义: *a = *b(a 是目标,b 是源) - # wiki 文档: c.Load(ptr, value) -> *ptr = *value; + # Load(a, b) 语义: *a = *b(a 是目标,b 是源) + # wiki 文档: Load(ptr, value) -> *ptr = *value; dst_val: ir.Value | None = self.HandleExprLlvm(Node.args[0]) src_val: ir.Value | None = self.HandleExprLlvm(Node.args[1]) if not src_val or not dst_val: @@ -188,13 +186,13 @@ class CSpecialCallHandle(BaseHandle): if not isinstance(src_val.type, ir.PointerType) or not isinstance(dst_val.type, ir.PointerType): return ir.Constant(ir.IntType(32), 0) pointee = dst_val.type.pointee - # c.Addr 统一返回 i8* 通用指针,丢失原始类型信息。 - # 若 dst 是 c.Addr(var),从 var 的 alloca 类型推断真实 pointee(如 i64), - # 否则 c.Load 只会按 i8 加载 1 字节(IEEE 754 double→u64 位重解释 bug)。 + # Addr 统一返回 i8* 通用指针,丢失原始类型信息。 + # 若 dst 是 Addr(var),从 var 的 alloca 类型推断真实 pointee(如 i64), + # 否则 Load 只会按 i8 加载 1 字节(IEEE 754 double→u64 位重解释 bug)。 if (isinstance(pointee, ir.IntType) and pointee.width == 8 and isinstance(Node.args[0], ast.Call) - and isinstance(Node.args[0].func, ast.Attribute) - and Node.args[0].func.attr == 'Addr' + and isinstance(Node.args[0].func, ast.Name) + and Node.args[0].func.id == 'Addr' and Node.args[0].args and isinstance(Node.args[0].args[0], ast.Name)): var_name = Node.args[0].args[0].id @@ -210,11 +208,11 @@ class CSpecialCallHandle(BaseHandle): Gen: LlvmGeneratorMixin = self.Trans.LlvmGen if not Node.args: return ir.Constant(ir.IntType(64), 0) - # 检测嵌套 c.Deref(c.Deref(...)):设置标志让内层 Deref 加载为指针 + # 检测嵌套 Deref(Deref(...)):设置标志让内层 Deref 加载为指针 IsNestedDeref: bool = ( isinstance(Node.args[0], ast.Call) - and isinstance(Node.args[0].func, ast.Attribute) - and Node.args[0].func.attr == 'Deref' + and isinstance(Node.args[0].func, ast.Name) + and Node.args[0].func.id == 'Deref' ) if IsNestedDeref: Gen._nested_deref_load_ptr = True @@ -236,11 +234,11 @@ class CSpecialCallHandle(BaseHandle): if Loaded is not None: return Loaded # 读取宽度只由指针的 pointee 类型决定(_load 按 arg_val.type.pointee - # 加载一个元素):pointee 是 i8(t.CPtr / void* / str / bytes)即恒读 - # 1 字节,不再按赋值目标注解反推宽度——那会让同一处 c.Deref(i8*) 的 + # 加载一个元素):pointee 是 i8(CPtr / void* / str / bytes)即恒读 + # 1 字节,不再按赋值目标注解反推宽度——那会让同一处 Deref(i8*) 的 # 读取宽度取决于它是否恰好出现在带注解赋值的 RHS 里。需要 4/8 字节等 # 更宽读取时,由调用点显式给出元素类型指针后再解引用 - # (c.Deref((int | t.CPtr)(p)) / c.Deref(t.CUInt64T(p, t.CPtr)))。 + # (Deref((int | CPtr)(p)) / Deref(CUInt64T(p, CPtr)))。 Loaded = Gen._load(arg_val, name="deref") if Loaded is not None: return Loaded @@ -295,9 +293,7 @@ class TSpecialCallHandle(BaseHandle): IsPtr_cast = False if len(Node.args) >= 2: second_arg = Node.args[1] - if isinstance(second_arg, ast.Attribute) and isinstance(second_arg.value, ast.Name) and IsTModule(second_arg.value.id, self.Trans.SymbolTable) and second_arg.attr == 'CPtr': - IsPtr_cast = True - elif isinstance(second_arg, ast.Name) and second_arg.id == 'CPtr': + if isinstance(second_arg, ast.Name) and second_arg.id == 'CPtr': IsPtr_cast = True if IsPtr_cast: return self._HandleTPtrCastLlvm(Node, attr) @@ -317,8 +313,8 @@ class TSpecialCallHandle(BaseHandle): ptr_count: int = 0 for i in range(1, len(Node.args)): type_arg = Node.args[i] - if isinstance(type_arg, ast.Attribute) and isinstance(type_arg.value, ast.Name) and IsTModule(type_arg.value.id, self.Trans.SymbolTable): - type_attr = type_arg.attr + if isinstance(type_arg, ast.Name): + type_attr = type_arg.id _PREFIX_MAP: dict[str, str] = { 'CUnsigned': 'unsigned', 'CSigned': 'signed', 'CConst': 'const', 'CVolatile': 'volatile', @@ -344,7 +340,7 @@ class TSpecialCallHandle(BaseHandle): Gen: LlvmGeneratorMixin = self.Trans.LlvmGen if attr in ('CChar', 'CUnsignedChar'): first_arg = Node.args[0] - if isinstance(first_arg, ast.Call) and isinstance(first_arg.func, ast.Attribute) and isinstance(first_arg.func.value, ast.Name) and IsTModule(first_arg.func.value.id, self.Trans.SymbolTable) and first_arg.func.attr == 'CInt' and first_arg.args: + if isinstance(first_arg, ast.Call) and isinstance(first_arg.func, ast.Name) and first_arg.func.id == 'CInt' and first_arg.args: inner_val = self.HandleExprLlvm(first_arg.args[0]) if isinstance(inner_val.type, ir.PointerType): return Gen.builder.bitcast(inner_val, ir.PointerType(ir.IntType(8)), name=f"c{attr.lower()}_ptr_from_cint") diff --git a/lib/core/Handles/HandlesTypeMerge.py b/lib/core/Handles/HandlesTypeMerge.py index 1c8fc82..36562cc 100644 --- a/lib/core/Handles/HandlesTypeMerge.py +++ b/lib/core/Handles/HandlesTypeMerge.py @@ -5,10 +5,10 @@ if TYPE_CHECKING: from typing import List from lib.core.Handles.HandlesBase import BaseHandle, CTypeHelper, CTypeInfo from lib.core.SymbolUtils import ( - IsTModule, IsListAnnotation, IsPtrSubscriptNode, IsCPtrMarkerNode, + IsListAnnotation, IsPtrSubscriptNode, IsCPtrMarkerNode, DesugarPtrSubscriptToUnion) -from lib.includes import t -import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib/includes) +from lib.core import TypeSystem +import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib) import vast as ast @@ -17,7 +17,7 @@ class HandlesTypeMerge(BaseHandle): def _MakeVoidCTypeInfo(self) -> CTypeInfo: Info = CTypeInfo() - Info.BaseType = t.CVoid + Info.BaseType = TypeSystem.CVoid return Info @staticmethod @@ -49,7 +49,7 @@ class HandlesTypeMerge(BaseHandle): if isinstance(Node, ast.Name): TypeName = Node.id - t_c_imported = getattr(self.Trans, '_t_c_imported_names', {}) + t_c_imported = getattr(self.Trans, '_from_import_aliases', {}) if TypeName in t_c_imported: src_module, src_name = t_c_imported[TypeName] virtual_attr = ast.Attribute( @@ -59,10 +59,47 @@ class HandlesTypeMerge(BaseHandle): ) ast.copy_location(virtual_attr, Node) return self.GetCTypeInfo(virtual_attr) + if TypeName in ('CRef', 'CTempRef'): + Info = CTypeInfo() + Info.PtrCount = 1 + Info.BaseType = TypeSystem.CVoid + return Info + BuiltinCls: type | None = CTypeHelper.GetTModuleCType(TypeName) + if BuiltinCls is not None and BuiltinCls is not TypeSystem.CType: + Info = CTypeInfo() + if BuiltinCls == TypeSystem.CArrayPtr: + Info.IsArrayPtr = True + Info.BaseType = TypeSystem.CVoid + return Info + if BuiltinCls == TypeSystem.CPtr: + Info.PtrCount = 1 + Info.BaseType = TypeSystem.CVoid + return Info + if BuiltinCls == TypeSystem.CConst: + Info.DataConst = True + Info.BaseType = TypeSystem.CVoid + return Info + if BuiltinCls == TypeSystem.CVolatile: + Info.DataVolatile = True + Info.BaseType = TypeSystem.CVoid + return Info + if BuiltinCls in (TypeSystem.CInline, TypeSystem.CStatic, + TypeSystem.CExtern, TypeSystem.CExport): + Info.Storage = BuiltinCls() + Info.BaseType = TypeSystem.CVoid + return Info + if BuiltinCls in (TypeSystem.BigEndian, TypeSystem.LittleEndian): + Info.BaseType = TypeSystem.CInt() + Info.ByteOrder = 'big' if BuiltinCls == TypeSystem.BigEndian else 'little' + return Info + Info.BaseType = BuiltinCls + if issubclass(BuiltinCls, TypeSystem.CDefine): + Info.IsDefine = True + return Info Entry = self.Trans.SymbolTable.lookup(TypeName) if Entry and Entry.IsTypedef: if isinstance(Entry, CTypeInfo) and Entry.BaseType: - if not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0: + if not isinstance(Entry.BaseType, (TypeSystem._CTypedef,)) or Entry.PtrCount > 0: Result = Entry.Copy() Result.IsTypedef = True Result.Name = TypeName @@ -91,7 +128,7 @@ class HandlesTypeMerge(BaseHandle): return Resolved return Entry # REnum 优先于 IsEnum 处理(REnum 同时有 IsEnum=True 和 IsStruct=True) - # 必须设置 Name 和 PtrCount=1,否则 BinOp `LLVMType | t.CPtr` 合并后丢失 REnum 语义 + # 必须设置 Name 和 PtrCount=1,否则 BinOp `LLVMType | CPtr` 合并后丢失 REnum 语义 if isinstance(Entry, CTypeInfo) and Entry.IsRenum: Result = Entry.Copy() Result.Name = TypeName @@ -107,14 +144,14 @@ class HandlesTypeMerge(BaseHandle): # 建出结构体的类(跨模块 import 的类)。 # 只查①漏②时的现场:`rawptr[Constant]`(includes/ast/exprs.vp:59 的 # accessor,`class Constant` 声明在同文件更后面)在导入侧解析时该名先命中 - # 平坦符号表里的枚举成员 `Constant: t.State`(ast/base.vp)→ 走下方 - # `Entry.IsEnum` 分支返回枚举 → 与 t.CPtr 合并后经 _ctype_to_llvm 的 + # 平坦符号表里的枚举成员 `Constant: State`(ast/base.vp)→ 走下方 + # `Entry.IsEnum` 分支返回枚举 → 与 CPtr 合并后经 _ctype_to_llvm 的 # IsEnum 分支(枚举名未登记 ⇒ 宽度退化为 i32)得 **i32\***,与调用点实参 # %".Constant"* 分裂 → FuncGen._adjust_args fail-fast。 # 查②后 BaseType=CStruct('Constant'),_get_or_create_struct 会按 # `_struct_sha1_map` 拼出 `".Constant"`(BaseGen.py:527-528), # 与声明端/实参同一结构体对象。 - # 但必须排除**枚举类型本身**(如 `class ASTKind(t.CEnum)` 的注解 `x: ASTKind`): + # 但必须排除**枚举类型本身**(如 `class ASTKind(CEnum)` 的注解 `x: ASTKind`): # _struct_sha1_map 是按 .vpi 里全部 ClassDef 建的,枚举类也在其中;若一并 # 当结构体,枚举注解会被建成 opaque struct,与 i32 错位 # (现场:'IntType' object has no attribute 'is_opaque')。 @@ -132,7 +169,7 @@ class HandlesTypeMerge(BaseHandle): TypeName in _Gen.structs or TypeName in getattr(_Gen, '_struct_sha1_map', {})): Result = CTypeInfo() - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.IsStruct = True Result.Name = TypeName Result.PtrCount = 1 @@ -141,19 +178,19 @@ class HandlesTypeMerge(BaseHandle): return Entry.Copy() if isinstance(Entry, dict) and Entry.get('IsEnum'): Result = CTypeInfo() - Result.BaseType = t.CEnum(TypeName) + Result.BaseType = TypeSystem.CEnum(TypeName) Result.IsEnum = True return Result # 检测结构体类型 (CTypeInfo with IsStruct=True, 来自 _InsertClassSymbol) if isinstance(Entry, CTypeInfo) and Entry.IsStruct: Result = Entry.Copy() if Result.BaseType is None: - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.Name = TypeName Result.PtrCount = 1 # struct 变量默认为指针 return Result # [builtins 最后匹配] 常规路径全部 miss 后查 includes/builtins.vp 的 - # CTypedef(size_t → t.CSizeT、rawptr → t.CPtr 内置等),对齐 + # CTypedef(size_t → CSizeT、rawptr → CPtr 内置等),对齐 # TypeAnnotationResolver._from_node_name 兜底,避免裸名被误判为 # 命名结构体(main2.vp `a: size_t` → alloca %...size_t 根因)。 try: @@ -184,6 +221,10 @@ class HandlesTypeMerge(BaseHandle): else: return self._MakeVoidCTypeInfo() + if ModulePath in ('t', 'c'): + raise TypeError( + f"[TPC] 类型注解不再接受 \"{ModulePath}.\" 模块前缀;" + f"请直接写内建类型名(如 CPtr、CInt、CArray)。") # 解析 import 别名: 如 import fat32_types as types -> types -> fat32_types if ModulePath: import_aliases = self.Trans.SymbolTable.import_aliases @@ -200,79 +241,6 @@ class HandlesTypeMerge(BaseHandle): if getattr(self.Trans, 'DebugFile', None): self.Trans.DebugPrint(f"[GetCTypeInfo-Attribute] 查询: '{TypeName}' ModulePath: {ModulePath}") - if ModulePath == 't' and TypeName == 'State': - Info = CTypeInfo() - Info.BaseType = t.CVoid - Info.IsState = True - return Info - - if ModulePath == 't' or (ModulePath and ModulePath.startswith('t.')): - # 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`,非真实类):与 - # t.CPtr 同形的「一层指针」,使 `T | t.CRef` 合并为 T*(pointer 层 +1)。 - if TypeName in ('CRef', 'CTempRef'): - Info = CTypeInfo() - Info.PtrCount = 1 - Info.BaseType = t.CVoid - return Info - if self._IsTModuleType(TypeName): - TypeClass = CTypeHelper.GetTModuleCType(TypeName) or getattr(t, TypeName, None) - if TypeClass == t.CArrayPtr: - Info = CTypeInfo() - Info.IsArrayPtr = True - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CPtr: - Info = CTypeInfo() - Info.PtrCount = 1 - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CConst: - Info = CTypeInfo() - Info.DataConst = True - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CVolatile: - Info = CTypeInfo() - Info.DataVolatile = True - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CInline: - Info = CTypeInfo() - Info.Storage = t.CInline() - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CStatic: - Info = CTypeInfo() - Info.Storage = t.CStatic() - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CExtern: - Info = CTypeInfo() - Info.Storage = t.CExtern() - Info.BaseType = t.CVoid - return Info - elif TypeClass == t.CExport: - Info = CTypeInfo() - Info.Storage = t.CExport() - Info.BaseType = t.CVoid - return Info - elif TypeClass in (t.BigEndian, t.LittleEndian): - Info = CTypeInfo() - Info.BaseType = t.CInt() - Info.ByteOrder = 'big' if TypeClass == t.BigEndian else 'little' - return Info - elif TypeClass: - Info = CTypeInfo() - Info.BaseType = TypeClass - # 治本修复:t.CDefine 注解必须设置 IsDefine=True, - # 否则预扫描 (LlvmGenerator.py) 和主处理 (HandlesAnnAssign.py) - # 都无法识别 CDefine 常量,导致 FOREGROUND_GREEN 等解析为 0 - if isinstance(TypeClass, type) and issubclass(TypeClass, t.CDefine): - Info.IsDefine = True - return Info - elif CTypeHelper.GetCName(TypeName): - return self._MakeCTypeInfoFromName(CTypeHelper.GetCName(TypeName)) - FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName # 优先检查 Gen.structs:类名与枚举成员名冲突时(如 Import 既是 ASTKind.Import @@ -281,7 +249,7 @@ class HandlesTypeMerge(BaseHandle): _Gen = getattr(self.Trans, 'LlvmGen', None) if _Gen and TypeName in _Gen.structs: Result = CTypeInfo() - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.IsStruct = True Result.Name = TypeName Result.PtrCount = 1 @@ -299,7 +267,7 @@ class HandlesTypeMerge(BaseHandle): # 与声明端 %".CLS"* 分裂。 if _Gen is not None and TypeName in getattr(_Gen, '_struct_sha1_map', {}): Result = CTypeInfo() - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.IsStruct = True Result.Name = TypeName Result.PtrCount = 1 @@ -308,7 +276,7 @@ class HandlesTypeMerge(BaseHandle): Entry = self.Trans.SymbolTable.lookup(TypeName) if Entry and Entry.IsTypedef: if isinstance(Entry, CTypeInfo) and Entry.BaseType: - if not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0: + if not isinstance(Entry.BaseType, (TypeSystem._CTypedef,)) or Entry.PtrCount > 0: Result = Entry.Copy() Result.IsTypedef = True Result.Name = TypeName @@ -336,7 +304,7 @@ class HandlesTypeMerge(BaseHandle): Resolved.Name = TypeName return Resolved Result = CTypeInfo() - Result.BaseType = t._CTypedef(TypeName) + Result.BaseType = TypeSystem._CTypedef(TypeName) Result.IsTypedef = True Result.Name = TypeName return Result @@ -344,7 +312,7 @@ class HandlesTypeMerge(BaseHandle): # If BaseType is None but this is a class/struct, set BaseType to CStruct Result = Entry.Copy() if Result.BaseType is None: - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.IsStruct = True # struct 变量默认为指针(与 ast.Name 路径一致,见 line 121) # 同时确保 Name 字段被设置,供 ToString() 使用 @@ -363,7 +331,7 @@ class HandlesTypeMerge(BaseHandle): ReturnType = ReturnTypeInfo else: ReturnType = CTypeInfo() - ReturnType.BaseType = t.CVoid() + ReturnType.BaseType = TypeSystem.CVoid() ParamTypes = [] ParamNames = [] @@ -399,70 +367,44 @@ class HandlesTypeMerge(BaseHandle): Info.FuncPtrParams = list(zip(ParamNames, ParamTypes)) return Info + if isinstance(Node.func, ast.Name): + BuiltinCls: type | None = CTypeHelper.GetTModuleCType(Node.func.id) + if BuiltinCls is not None and BuiltinCls is not TypeSystem.CType: + if BuiltinCls == TypeSystem.State: + Info = CTypeInfo() + Info.IsState = True + return Info + if BuiltinCls == TypeSystem.Bit: + Width: int = 1 + if Node.args and isinstance(Node.args[0], ast.Constant): + Width = Node.args[0].value + Info = CTypeInfo() + Info.IsBitField = True + Info.BitWidth = Width + Info.BaseType = TypeSystem.CInt + return Info + Info = CTypeInfo() + Info.BaseType = BuiltinCls + return Info + if isinstance(Node.func, ast.Attribute) and isinstance(Node.func.value, ast.Name): ModuleName = Node.func.value.id TypeName = Node.func.attr - if ModuleName == 't' and CTypeHelper.GetTModuleCType(TypeName) == t._CTypedef and Node.args: - TypeArg = Node.args[0] - if isinstance(TypeArg, ast.Name): - return TypeArg.id - elif isinstance(TypeArg, ast.Attribute): - AttrModule = TypeArg.value.id if isinstance(TypeArg.value, ast.Name) else None - AttrName = TypeArg.attr - if AttrModule == 't' and getattr(t, AttrName, None): - TypeObj = getattr(t, AttrName) - if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType): - return TypeObj.__name__ - return AttrName - elif isinstance(TypeArg, ast.Constant): - return str(TypeArg.value) - - if ModuleName in self.Trans._UserTypeModules: - module = self.Trans._UserTypeModules[ModuleName] - if getattr(module, TypeName, None): - TypeObj = getattr(module, TypeName) - if isinstance(TypeObj, type): - if issubclass(TypeObj, t.CType): - return TypeObj.__name__ - - if ModuleName == 't': - TypeObj = CTypeHelper.GetTModuleCType(TypeName) - if TypeObj is None: - TypeObj = getattr(t, TypeName, None) - if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType): - Result = CTypeInfo() - Result.BaseType = TypeObj - return Result - - if ModuleName == 't' and TypeName == 'State': - Result = CTypeInfo() - Result.IsState = True - return Result - - if ModuleName == 't' and TypeName == 'Bit': - if Node.args and isinstance(Node.args[0], ast.Constant): - BitWidth = Node.args[0].value - Result = CTypeInfo() - Result.IsBitField = True - Result.BitWidth = BitWidth - Result.BaseType = t.CInt - return Result - Result = CTypeInfo() - Result.BaseType = t.CVoid + Result.BaseType = TypeSystem.CVoid return Result elif isinstance(Node, ast.Subscript): if (isinstance(Node.value, ast.Attribute) and isinstance(Node.value.value, ast.Name) - and IsTModule(Node.value.value.id, self.Trans.SymbolTable) + and Node.value.attr == 'Bit'): if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int): Result = CTypeInfo() Result.IsBitField = True Result.BitWidth = Node.slice.value - Result.BaseType = t.CInt + Result.BaseType = TypeSystem.CInt return Result return self._HandleSubscript(Node) @@ -488,21 +430,21 @@ class HandlesTypeMerge(BaseHandle): """澶勭悊 Subscript 鑺傜偣锛屼娇鐢?CTypeInfo 鏍戝舰缁撴瀯鍒嗘瀽 AST 例如? - t.CVoid[5] -> void *[5] - t.CPtr[t.CPtr[t.CPtr]][5][6] -> void ***[5][6] - t.CArrayPtr[t.CArrayPtr] -> void *(*)[] - t.CPtr[t.CArrayPtr[t.CArrayPtr]] -> void *(*(*))[] + CVoid[5] -> void *[5] + CPtr[CPtr[CPtr]][5][6] -> void ***[5][6] + CArrayPtr[CArrayPtr] -> void *(*)[] + CPtr[CArrayPtr[CArrayPtr]] -> void *(*(*))[] """ - # 指针下标(rawptr[T] 内置裸指针 / t.CPtr[T] 下标指针,含裸名 CPtr[T]) - # 折叠为等价的联合写法 `T | t.CPtr` 后交给 MergeTypes 统一解析:内层 T + # 指针下标(rawptr[T] 内置裸指针 / CPtr[T] 下标指针,含裸名 CPtr[T]) + # 折叠为等价的联合写法 `T | CPtr` 后交给 MergeTypes 统一解析:内层 T # 因此走通用解析路径(含跨模块类经 Gen.structs 反查 SHA1 前缀),指针 - # 层数与源码 `T | t.CPtr` 完全一致(此前 t.CPtr[ast.AST] 在此得 - # AST**(比 declare/`AST | t.CPtr` 多一层)、rawptr[ast.AST] 退化为 + # 层数与源码 `T | CPtr` 完全一致(此前 CPtr[ast.AST] 在此得 + # AST**(比 declare/`AST | CPtr` 多一层)、rawptr[ast.AST] 退化为 # CVoid/1 → i8*)。 if IsPtrSubscriptNode(Node, self.Trans.SymbolTable): return self.MergeTypes(DesugarPtrSubscriptToUnion(Node, self.Trans.SymbolTable)) - # 判据自洽守卫(fail-fast):base 是指针标记(`rawptr` / `t.CPtr` / 裸名 + # 判据自洽守卫(fail-fast):base 是指针标记(`rawptr` / `CPtr` / 裸名 # `CPtr` / 别名 `X[...]`,见 IsPtrSubscriptNode)却被上面那条判据漏掉 ⇒ # 两处判据分裂(内部不变量被破坏)。历史行为是落到下方 CollectAll 当成 # 「数组下标」解析,**静默**产出"基座 void + 多层指针"(如 i8**),与 @@ -526,7 +468,7 @@ class HandlesTypeMerge(BaseHandle): if isinstance(value_node, ast.Attribute): VtInfo = self.GetCTypeInfo(value_node) - if isinstance(value_node, ast.Attribute) and value_node.attr == 'Callable' and isinstance(value_node.value, ast.Name) and IsTModule(value_node.value.id, self.Trans.SymbolTable): + if isinstance(value_node, ast.Attribute) and value_node.attr == 'Callable' and isinstance(value_node.value, ast.Name) : if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2: params_list = slice_node.elts[0] return_node = slice_node.elts[1] @@ -549,7 +491,7 @@ class HandlesTypeMerge(BaseHandle): ReturnType = ReturnTypeInfo else: ReturnType = CTypeInfo() - ReturnType.BaseType = t.CVoid() + ReturnType.BaseType = TypeSystem.CVoid() Info = CTypeInfo() Info.IsFuncPtr = True Info.FuncPtrReturn = ReturnType @@ -592,23 +534,23 @@ class HandlesTypeMerge(BaseHandle): ResultInfo.ArrayPtr.IsArrayPtr = True elif VtInfo and VtInfo.PtrCount == 1 and not VtInfo.ArrayPtr: ResultInfo = CTypeInfo() - ResultInfo.BaseType = t.CVoid + ResultInfo.BaseType = TypeSystem.CVoid ResultInfo.PtrCount = 1 if isinstance(slice_node, ast.Subscript): inner_info = CollectAll(slice_node) if inner_info and inner_info.PtrCount > 0: ResultInfo.PtrCount += inner_info.PtrCount - if inner_info.BaseType and not isinstance(inner_info.BaseType, t.CVoid): + if inner_info.BaseType and not isinstance(inner_info.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = inner_info.BaseType elif inner_info and inner_info.ArrayPtr: ResultInfo.ArrayPtr = inner_info - elif inner_info and inner_info.BaseType and not isinstance(inner_info.BaseType, t.CVoid): + elif inner_info and inner_info.BaseType and not isinstance(inner_info.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = inner_info.BaseType elif isinstance(slice_node, ast.Attribute): SliceVtInfo = self.GetCTypeInfo(slice_node) if SliceVtInfo and SliceVtInfo.PtrCount == 1 and not SliceVtInfo.ArrayPtr: ResultInfo.PtrCount = 2 - if SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid): + if SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = SliceVtInfo.BaseType elif SliceVtInfo and SliceVtInfo.IsArrayPtr: inner = CTypeInfo() @@ -616,13 +558,13 @@ class HandlesTypeMerge(BaseHandle): ResultInfo.ArrayPtr = inner elif SliceVtInfo and SliceVtInfo.ArrayPtr: ResultInfo.ArrayPtr = SliceVtInfo - elif SliceVtInfo and SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid): + elif SliceVtInfo and SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = SliceVtInfo.BaseType elif isinstance(slice_node, ast.Name): - SliceType = getattr(t, slice_node.id, None) - if SliceType == t.CPtr: + SliceType = getattr(TypeSystem, slice_node.id, None) + if SliceType == TypeSystem.CPtr: ResultInfo.PtrCount += 1 - elif SliceType == t.CArrayPtr: + elif SliceType == TypeSystem.CArrayPtr: inner = CTypeInfo() inner.ArrayPtr = CTypeInfo() ResultInfo.ArrayPtr = inner @@ -632,7 +574,7 @@ class HandlesTypeMerge(BaseHandle): merged = self.MergeTypes(slice_node) if merged: ResultInfo.PtrCount += merged.PtrCount - if merged.BaseType and not isinstance(merged.BaseType, t.CVoid): + if merged.BaseType and not isinstance(merged.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = merged.BaseType if merged.ArrayPtr: ResultInfo.ArrayPtr = merged.ArrayPtr @@ -657,10 +599,10 @@ class HandlesTypeMerge(BaseHandle): if isinstance(slice_node, ast.Constant): ResultInfo.ArrayDims.append(str(slice_node.value)) elif isinstance(slice_node, ast.Name): - SliceType = getattr(t, slice_node.id, None) - if SliceType == t.CPtr: + SliceType = getattr(TypeSystem, slice_node.id, None) + if SliceType == TypeSystem.CPtr: ResultInfo.PtrCount += 1 - elif SliceType == t.CArrayPtr: + elif SliceType == TypeSystem.CArrayPtr: ResultInfo.ArrayPtr = CTypeInfo() else: ResultInfo.ArrayDims.append(slice_node.id) @@ -670,13 +612,13 @@ class HandlesTypeMerge(BaseHandle): SliceVtInfo = self.GetCTypeInfo(slice_node) if SliceVtInfo and SliceVtInfo.PtrCount >= 1 and not SliceVtInfo.ArrayPtr: ResultInfo.PtrCount += SliceVtInfo.PtrCount - if SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid): + if SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = SliceVtInfo.BaseType elif SliceVtInfo and SliceVtInfo.IsArrayPtr: NewInfo = CTypeInfo() NewInfo.ArrayPtr = ResultInfo ResultInfo = NewInfo - elif SliceVtInfo and SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid): + elif SliceVtInfo and SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, TypeSystem.CVoid): ResultInfo.BaseType = SliceVtInfo.BaseType elif isinstance(slice_node, ast.Subscript): InnerNode = CollectAll(slice_node) @@ -690,10 +632,10 @@ class HandlesTypeMerge(BaseHandle): elif isinstance(slice_node, ast.Constant): ResultInfo.ArrayDims.append(str(slice_node.value)) elif isinstance(slice_node, ast.Name): - SliceType = getattr(t, slice_node.id, None) - if SliceType == t.CPtr: + SliceType = getattr(TypeSystem, slice_node.id, None) + if SliceType == TypeSystem.CPtr: ResultInfo.PtrCount += 1 - elif SliceType == t.CArrayPtr: + elif SliceType == TypeSystem.CArrayPtr: ResultInfo.ArrayPtr = CTypeInfo() else: ResultInfo.ArrayDims.append(slice_node.id) @@ -708,18 +650,18 @@ class HandlesTypeMerge(BaseHandle): if not isinstance(slice_node, ast.Tuple): ElementType = self._GetCTypeInfoInternal(slice_node) if ElementType and isinstance(ElementType, CTypeInfo): - ResultInfo.BaseType = ElementType.BaseType if ElementType.BaseType else t.CVoid() + ResultInfo.BaseType = ElementType.BaseType if ElementType.BaseType else TypeSystem.CVoid() ResultInfo.PtrCount = ElementType.PtrCount + 1 ResultInfo.IsFuncPtr = ElementType.IsFuncPtr ResultInfo.FuncPtrReturn = ElementType.FuncPtrReturn ResultInfo.FuncPtrParams = ElementType.FuncPtrParams else: - ResultInfo.BaseType = t.CVoid() + ResultInfo.BaseType = TypeSystem.CVoid() ResultInfo.PtrCount = 1 elif isinstance(slice_node, ast.Tuple) and len(slice_node.elts) >= 1: ElementType = self._GetCTypeInfoInternal(slice_node.elts[0]) if ElementType and isinstance(ElementType, CTypeInfo): - ResultInfo.BaseType = ElementType.BaseType if ElementType.BaseType else t.CVoid() + ResultInfo.BaseType = ElementType.BaseType if ElementType.BaseType else TypeSystem.CVoid() ResultInfo.PtrCount = ElementType.PtrCount ResultInfo.IsFuncPtr = ElementType.IsFuncPtr ResultInfo.FuncPtrReturn = ElementType.FuncPtrReturn @@ -764,14 +706,14 @@ class HandlesTypeMerge(BaseHandle): slice_res = self.Trans.ExprCallHandle._resolve_generic_slice_type(slice_node) type_arg_str = slice_res[0] if slice_res else self.Trans.ExprCallHandle._resolve_type_arg_str(slice_node) full_spec_name: str = f'{value_node.id}[{type_arg_str}]' - ResultInfo.BaseType = t.CStruct(name=full_spec_name) + ResultInfo.BaseType = TypeSystem.CStruct(name=full_spec_name) ResultInfo.Name = full_spec_name ResultInfo.IsStruct = True ResultInfo.PtrCount = 1 # 触发泛型特化发射:确保特化的方法被发射 + struct sha1 注册 # 与局部变量 AnnAssign 路径一致;否则函数参数注解路径 # 只构建 mangled 名,方法调用分派时 class_sha1=None 导致 - # "Undefined method" 错误(如 lst.__len__() 在 list[T] | t.CPtr 参数上) + # "Undefined method" 错误(如 lst.__len__() 在 list[T] | CPtr 参数上) # _specialize_generic_class 内部有 spec_key 去重,重复调用安全 if hasattr(self.Trans, 'ExprCallHandle') and self.Trans.ExprCallHandle is not None: self.Trans.ExprCallHandle._ResolveGenericSlice(node) @@ -801,14 +743,14 @@ class HandlesTypeMerge(BaseHandle): _ig_res = self.Trans.ExprCallHandle._resolve_generic_slice_type(_ig_elt) _ig_args.append(_ig_res[0] if _ig_res else self.Trans.ExprCallHandle._resolve_type_arg_str(_ig_elt)) _ig_spec: str = f'{_inner_gsub.value.id}[' + ']['.join(_ig_args) + ']' - ResultInfo.BaseType = t.CStruct(name=_ig_spec) + ResultInfo.BaseType = TypeSystem.CStruct(name=_ig_spec) ResultInfo.Name = _ig_spec ResultInfo.IsStruct = True ResultInfo.PtrCount = 1 self.Trans.ExprCallHandle._ResolveGenericSlice(_inner_gsub) return ResultInfo # [builtins 最后匹配] base 为 builtins 指针 typedef - # (rawptr → t.CPtr):rawptr[X] 等价 X*(对齐 VPC + # (rawptr → CPtr):rawptr[X] 等价 X*(对齐 VPC # Subscript 语义),委托 TypeAnnotationResolver 统一解析, # 避免被误当作 'rawptr[X]' 结构体/数组维度处理。 try: @@ -823,10 +765,10 @@ class HandlesTypeMerge(BaseHandle): if isinstance(slice_node, ast.Constant): ResultInfo.ArrayDims.append(str(slice_node.value)) elif isinstance(slice_node, ast.Name): - SliceType = getattr(t, slice_node.id, None) - if SliceType == t.CPtr: + SliceType = getattr(TypeSystem, slice_node.id, None) + if SliceType == TypeSystem.CPtr: ResultInfo.PtrCount += 1 - elif SliceType == t.CArrayPtr: + elif SliceType == TypeSystem.CArrayPtr: ResultInfo.ArrayPtr = CTypeInfo() else: ResultInfo.ArrayDims.append(slice_node.id) @@ -849,7 +791,7 @@ class HandlesTypeMerge(BaseHandle): result.ArrayPtr = CTypeInfo() return result elif VtInfo and VtInfo.PtrCount == 1 and not VtInfo.ArrayPtr: - result.BaseType = t.CVoid + result.BaseType = TypeSystem.CVoid result.PtrCount = 1 return result elif VtInfo and VtInfo.BaseType: @@ -870,10 +812,10 @@ class HandlesTypeMerge(BaseHandle): """递归收集所有操作数的类型(用于一次性合并)""" Types = [] - # 指针下标(rawptr[T] / t.CPtr[T])先折叠成等价的 `T | t.CPtr`:使 - # `rawptr[T] | t.CPtr` 与 `T | t.CPtr | t.CPtr` 拉平成同一组操作数 + # 指针下标(rawptr[T] / CPtr[T])先折叠成等价的 `T | CPtr`:使 + # `rawptr[T] | CPtr` 与 `T | CPtr | CPtr` 拉平成同一组操作数 # (否则折叠结果作为单个 Subscript 操作数参与合并,指针层数少算一层); - # t.CPtr[T] 与 rawptr[T] 同一条规则(见 SymbolUtils.IsPtrSubscriptNode)。 + # CPtr[T] 与 rawptr[T] 同一条规则(见 SymbolUtils.IsPtrSubscriptNode)。 if IsPtrSubscriptNode(Node, self.Trans.SymbolTable): Node = DesugarPtrSubscriptToUnion(Node, self.Trans.SymbolTable) @@ -890,12 +832,12 @@ class HandlesTypeMerge(BaseHandle): if isinstance(Node, ast.Call): if isinstance(Node.func, ast.Name) and Node.func.id == 'callable': return self.GetCTypeInfo(Node) - elif isinstance(Node.func, ast.Attribute) and CTypeHelper.GetTModuleCType(Node.func.attr) == t._CTypedef: + elif isinstance(Node.func, ast.Attribute) and CTypeHelper.GetTModuleCType(Node.func.attr) == TypeSystem._CTypedef: return self.GetCTypeInfo(Node) elif isinstance(Node.func, ast.Attribute) and Node.func.attr == 'Bit': if Node.args and isinstance(Node.args[0], ast.Constant): Result = CTypeInfo() - Result.BaseType = t.CInt + Result.BaseType = TypeSystem.CInt Result.IsBitField = True Result.BitWidth = Node.args[0].value return Result @@ -903,11 +845,11 @@ class HandlesTypeMerge(BaseHandle): elif isinstance(Node, ast.Subscript): if (isinstance(Node.value, ast.Attribute) and isinstance(Node.value.value, ast.Name) - and IsTModule(Node.value.value.id, self.Trans.SymbolTable) + and Node.value.attr == 'Bit'): if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int): Result = CTypeInfo() - Result.BaseType = t.CInt + Result.BaseType = TypeSystem.CInt Result.IsBitField = True Result.BitWidth = Node.slice.value return Result @@ -916,7 +858,7 @@ class HandlesTypeMerge(BaseHandle): return self.GetCTypeInfo(Node) def MergeTypes(self, Node: ast.BinOp): - """处理类型组合,如 t.CInt | t.CPtr ?t.CStatic | t.CInt + """处理类型组合,如 CInt | CPtr ?CStatic | CInt 这是 | 运算符的类型合并处理函数 收集所有操作数,一次性合? @@ -935,15 +877,15 @@ class HandlesTypeMerge(BaseHandle): LeftParts = [] current = Node.left while isinstance(current, ast.Attribute): - attr_type = getattr(t, current.attr, None) - if attr_type and isinstance(attr_type, type) and issubclass(attr_type, t.CType): + attr_type = getattr(TypeSystem, current.attr, None) + if attr_type and isinstance(attr_type, type) and issubclass(attr_type, TypeSystem.CType): LeftParts.insert(0, attr_type) current = current.value if isinstance(current, ast.Name): - name_type = getattr(t, current.id, None) - if name_type and isinstance(name_type, type) and issubclass(name_type, t.CType): + name_type = getattr(TypeSystem, current.id, None) + if name_type and isinstance(name_type, type) and issubclass(name_type, TypeSystem.CType): LeftParts.insert(0, name_type) - if LeftParts and LeftParts[-1] == t._CTypedef: + if LeftParts and LeftParts[-1] == TypeSystem._CTypedef: for type_item in AllTypes: if isinstance(type_item, CTypeInfo) and type_item.IsFuncPtr: type_item.IsTypedef = True @@ -956,7 +898,7 @@ class HandlesTypeMerge(BaseHandle): if isinstance(AllTypes[-1], CTypeInfo): Result.BaseType = AllTypes[-1].BaseType else: - Result.BaseType = t.CInt + Result.BaseType = TypeSystem.CInt Result.IsTypedef = True return Result @@ -968,37 +910,37 @@ class HandlesTypeMerge(BaseHandle): return CTypeInfo() Result = CTypeInfo() - # 统计 t.CPtr(CVoid + PtrCount=1)的个数,用于正确累加指针层数 - # 因为 (AST | t.CPtr) | t.CPtr 展开后会包含多个 t.CPtr,每个都需要累加 + # 统计 CPtr(CVoid + PtrCount=1)的个数,用于正确累加指针层数 + # 因为 (AST | CPtr) | CPtr 展开后会包含多个 CPtr,每个都需要累加 cptr_count: int = 0 for TypeItem in Types: if TypeItem is None: continue if TypeItem.IsDefine: - # t.CDefine 标记在 | 合并中传播(对齐 IsState): - # `int | t.CDefine`(define 宏函数返回注解)合并后仍保持 + # CDefine 标记在 | 合并中传播(对齐 IsState): + # `int | CDefine`(define 宏函数返回注解)合并后仍保持 # IsDefine=True,下游才能识别为编译期宏(alwaysinline/#define) Result.IsDefine = True if TypeItem.IsState: Result.IsState = True if not Result.Storage: - Result.Storage = t.CExport() + Result.Storage = TypeSystem.CExport() continue if TypeItem.IsBitField: - Result.BaseType = t.CInt + Result.BaseType = TypeSystem.CInt Result.IsBitField = True Result.BitWidth = TypeItem.BitWidth return Result if TypeItem.IsFuncPtr: - Result.BaseType = t.CVoid + Result.BaseType = TypeSystem.CVoid Result.IsFuncPtr = True Result.FuncPtrParams = TypeItem.FuncPtrParams Result.FuncPtrReturn = TypeItem.FuncPtrReturn return Result if TypeItem.IsTypedef: - if TypeItem.BaseType and (not isinstance(TypeItem.BaseType, (t._CTypedef,)) or TypeItem.PtrCount > 0): - if Result.BaseType is None or isinstance(Result.BaseType, (t.CVoid, t._CTypedef)): + if TypeItem.BaseType and (not isinstance(TypeItem.BaseType, (TypeSystem._CTypedef,)) or TypeItem.PtrCount > 0): + if Result.BaseType is None or isinstance(Result.BaseType, (TypeSystem.CVoid, TypeSystem._CTypedef)): Result.BaseType = TypeItem.BaseType Result.Name = TypeItem.Name Result.IsTypedef = True @@ -1011,9 +953,9 @@ class HandlesTypeMerge(BaseHandle): if TypeItem.OriginalType: Result.OriginalType = TypeItem.OriginalType continue - # 统计 t.CPtr(CVoid + PtrCount>0) - # 注意: t.CPtr[t.CPtr] 的 PtrCount=2(双重指针),需要完整累加 - if TypeItem.PtrCount > 0 and TypeItem.BaseType and (TypeItem.BaseType is t.CVoid or isinstance(TypeItem.BaseType, t.CVoid)): + # 统计 CPtr(CVoid + PtrCount>0) + # 注意: CPtr[CPtr] 的 PtrCount=2(双重指针),需要完整累加 + if TypeItem.PtrCount > 0 and TypeItem.BaseType and (TypeItem.BaseType is TypeSystem.CVoid or isinstance(TypeItem.BaseType, TypeSystem.CVoid)): cptr_count += TypeItem.PtrCount # BaseType 保持不变,只计数,后续统一累加 if TypeItem.IsRenum and TypeItem.Name: @@ -1025,29 +967,29 @@ class HandlesTypeMerge(BaseHandle): continue self._MergeCTypeInfoInto(Result, TypeItem) - # 对所有 t.CPtr 统一累加指针层数 - # 仅对 struct 类型吸收第一个 CPtr(struct 变量默认是指针,AST | t.CPtr = AST*)。 - # 对于本身已是指针的类型(如 bytes=CChar*),bytes | t.CPtr = i8**(不吸收)。 + # 对所有 CPtr 统一累加指针层数 + # 仅对 struct 类型吸收第一个 CPtr(struct 变量默认是指针,AST | CPtr = AST*)。 + # 对于本身已是指针的类型(如 bytes=CChar*),bytes | CPtr = i8**(不吸收)。 base_ptr_count: int = Result.PtrCount Result.PtrCount += cptr_count if Result.IsStruct and base_ptr_count > 0 and cptr_count > 0: Result.PtrCount -= 1 if Result.BaseType is None: - Result.BaseType = t.CVoid + Result.BaseType = TypeSystem.CVoid return Result def _MergeCTypeInfoInto(self, Target: CTypeInfo, Source: CTypeInfo): - if Source.PtrCount > 0 and Source.BaseType and (Source.BaseType is t.CVoid or isinstance(Source.BaseType, t.CVoid)): - # t.CPtr 的处理已提升到 _MergeAllComponentTypes 中统一计数累加, + if Source.PtrCount > 0 and Source.BaseType and (Source.BaseType is TypeSystem.CVoid or isinstance(Source.BaseType, TypeSystem.CVoid)): + # CPtr 的处理已提升到 _MergeAllComponentTypes 中统一计数累加, # 此处保留仅作为兜底(从其他路径直接调用 _MergeCTypeInfoInto 时) if Target.PtrCount < Source.PtrCount: Target.PtrCount = Source.PtrCount - elif Source.PtrCount > 0 and Source.BaseType and Source.BaseType is not t.CVoid and not isinstance(Source.BaseType, t.CVoid): - if Target.BaseType is None or Target.BaseType is t.CVoid or isinstance(Target.BaseType, t.CVoid): + elif Source.PtrCount > 0 and Source.BaseType and Source.BaseType is not TypeSystem.CVoid and not isinstance(Source.BaseType, TypeSystem.CVoid): + if Target.BaseType is None or Target.BaseType is TypeSystem.CVoid or isinstance(Target.BaseType, TypeSystem.CVoid): Target.BaseType = Source.BaseType - # 当 Target 已有 PtrCount(来自之前的 t.CPtr),累加而非替换 + # 当 Target 已有 PtrCount(来自之前的 CPtr),累加而非替换 Target.PtrCount = Source.PtrCount + Target.PtrCount elif Target.PtrCount == 0: Target.PtrCount = Source.PtrCount @@ -1055,25 +997,25 @@ class HandlesTypeMerge(BaseHandle): Target.PtrCount = Source.PtrCount elif Source.PtrCount > Target.PtrCount: Target.PtrCount = Source.PtrCount - if Source.BaseType and Source.BaseType is not t.CVoid and not isinstance(Source.BaseType, (t.CVoid, t._CTypedef)): + if Source.BaseType and Source.BaseType is not TypeSystem.CVoid and not isinstance(Source.BaseType, (TypeSystem.CVoid, TypeSystem._CTypedef)): if Target.BaseType is None: Target.BaseType = Source.BaseType - elif (Target.BaseType is t.CVoid or isinstance(Target.BaseType, t.CVoid)) and Target.PtrCount == 0: + elif (Target.BaseType is TypeSystem.CVoid or isinstance(Target.BaseType, TypeSystem.CVoid)) and Target.PtrCount == 0: Target.BaseType = Source.BaseType - elif (Source.BaseType is t.CVoid or isinstance(Source.BaseType, t.CVoid)) and Target.BaseType is None: + elif (Source.BaseType is TypeSystem.CVoid or isinstance(Source.BaseType, TypeSystem.CVoid)) and Target.BaseType is None: Target.BaseType = Source.BaseType - # Struct 名称保留:BinOp `list[AST | t.CPtr] | t.CPtr` 合并时, + # Struct 名称保留:BinOp `list[AST | CPtr] | CPtr` 合并时, # _HandleSubscript 已在 Source.Name 设置了特化名(如 'list[5dab8cb390496d22.ASTptr]'), # 合并后 Target.Name 必须保留此名称,否则 class_member_element_class # 无法获取正确的特化类名 → 方法分派 fallback 到错误的类 if Source.IsStruct and Source.Name and not Target.Name: Target.Name = Source.Name # 【IsStruct 必须随 Name 一起传播】`_MergeAllComponentTypes` 的 - # "struct 吸收第一个 t.CPtr"规则(见该函数 :1022-1027 的注释: - # struct 变量默认是指针 ⇒ `AST | t.CPtr = AST*`)以 `Result.IsStruct` 为**闸门**: + # "struct 吸收第一个 CPtr"规则(见该函数 :1022-1027 的注释: + # struct 变量默认是指针 ⇒ `AST | CPtr = AST*`)以 `Result.IsStruct` 为**闸门**: # 此前本函数只复制 Name、从不置 IsStruct ⇒ 闸门恒假 ⇒ 闸门后的 # `Result.PtrCount -= 1` 永不执行 ⇒ 「类 + CPtr」的联合(如 - # `list[str] | t.CPtr`)合并后指针层数**多算一层**(得 `list[str]**`,应为 + # `list[str] | CPtr`)合并后指针层数**多算一层**(得 `list[str]**`,应为 # `list[str]*`)⇒ 调用点/字段拿到的值类型 pointee 是指针而不是结构体 ⇒ # 类名在下游被当作通用指针处理(现场:`parts = s1.split(',')` 的返回值 # pointee 非结构体 ⇒ HandlesAssign 的类名推断整块跳过 ⇒ 随后 `parts[0]` @@ -1081,7 +1023,7 @@ class HandlesTypeMerge(BaseHandle): # 语义上这两个标志同源(合并结果就是那个 struct),故成对传播。 if Source.IsStruct: Target.IsStruct = True - # REnum 标志和名称保留(BinOp `LLVMType | t.CPtr` 合并时不能丢失 REnum 语义) + # REnum 标志和名称保留(BinOp `LLVMType | CPtr` 合并时不能丢失 REnum 语义) # 同时传播 IsStruct=True,让 CPtr 吸收逻辑生效(REnum 在内存布局上是 struct) if Source.IsRenum and Source.Name: Target.IsRenum = True @@ -1090,14 +1032,14 @@ class HandlesTypeMerge(BaseHandle): if not Target.Name: Target.Name = Source.Name if Source.IsTypedef and Source.Name: - if Source.BaseType and (not isinstance(Source.BaseType, (t._CTypedef,)) or Source.PtrCount > 0): - if Target.BaseType is None or isinstance(Target.BaseType, (t.CVoid, t._CTypedef)): + if Source.BaseType and (not isinstance(Source.BaseType, (TypeSystem._CTypedef,)) or Source.PtrCount > 0): + if Target.BaseType is None or isinstance(Target.BaseType, (TypeSystem.CVoid, TypeSystem._CTypedef)): Target.BaseType = Source.BaseType Target.IsTypedef = True Target.Name = Source.Name if Source.OriginalType: Target.OriginalType = Source.OriginalType - elif Target.BaseType is None or isinstance(Target.BaseType, (t.CVoid, t._CTypedef)): + elif Target.BaseType is None or isinstance(Target.BaseType, (TypeSystem.CVoid, TypeSystem._CTypedef)): if Source.OriginalType: if isinstance(Source.OriginalType, CTypeInfo) and Source.OriginalType.BaseType: Target.BaseType = Source.OriginalType.BaseType @@ -1110,10 +1052,10 @@ class HandlesTypeMerge(BaseHandle): Target.Name = Source.Name Target.OriginalType = Source.OriginalType else: - Target.BaseType = t.CStruct(name=Source.Name) + Target.BaseType = TypeSystem.CStruct(name=Source.Name) Target.IsStruct = True else: - Target.BaseType = t.CStruct(name=Source.Name) + Target.BaseType = TypeSystem.CStruct(name=Source.Name) Target.IsStruct = True if Source.ArrayPtr: if Target.ArrayPtr is None: diff --git a/lib/core/LLVMCG/BaseGen.py b/lib/core/LLVMCG/BaseGen.py index 6ecd363..e0debfc 100644 --- a/lib/core/LLVMCG/BaseGen.py +++ b/lib/core/LLVMCG/BaseGen.py @@ -4,8 +4,8 @@ import vast as ast import os import re import llvmlite.ir as ir -from lib.includes import t as _t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem as _t +from lib.core.TypeSystem import CTypeRegistry from lib.core.Handles.HandlesBase import CTypeInfo as _CTypeInfo, BuiltinTypeMap from lib.core.SymbolUtils import EnumIntWidth, _ENUM_DEFAULT_INT_WIDTH from lib.constants.config import DEFAULT_HOTSPOT_CALLEES @@ -351,7 +351,7 @@ class BaseGenMixin: self.loop_break_targets: list[ir.Block] = [] self.loop_continue_targets: list[ir.Block] = [] # 当前是否正处于 switch 的 case 语句体内(True=是)。供 `fallthrough` - # 标记语句(vast 脱糖为 c.NoBreak())判定合法性:只在 switch 的 case 体内 + # 标记语句(vast 脱糖为 NoBreak())判定合法性:只在 switch 的 case 体内 # 合法;写进 match(完全禁止 fallthrough)或 switch 之外一律 fail-fast。 self.in_switch_case: bool = False self.eh_jmp_buf_stack: list[ir.Value] = [] @@ -370,7 +370,7 @@ class BaseGenMixin: self.var_annotated_class: dict[str, str] = {} self.var_ptr_element: dict[str, bool] = {} # 全局变量的指针元素标志(持久,不受函数重置影响) - # 用于全局变量 _argv: bytes | t.CPtr 等,使 _argv[index] 使用 8 字节指针步长 + # 用于全局变量 _argv: bytes | CPtr 等,使 _argv[index] 使用 8 字节指针步长 self.global_var_ptr_element: dict[str, bool] = {} self.class_provides: dict[str, list[str]] = {} self.class_requires: dict[str, list[str]] = {} @@ -381,7 +381,7 @@ class BaseGenMixin: # 函数参数自动取地址模式: func_name -> [None, None, 'ref', 'temp', 'always', ...] # 'ref': &T — 实参非指针左值取址,右值 fail-fast # 'temp': &temp T — 实参非指针时在调用方建同型临时再取址 - # 'always': t.CAutoPtr — 无条件取地址 + # 'always': CAutoPtr — 无条件取地址 self._auto_addr_params: dict[str, list[str | None]] = {} self.global_struct_class: dict[str, str] = {} self.var_type_info: dict[str, Any] = {} @@ -392,7 +392,7 @@ class BaseGenMixin: # 函数作用域层(随函数出栈清空,清零点 HandlesFunctions 函数出口): # var_const_flags 变量(局部/形参)自身 const # var_volatile_flags 变量自身 volatile - # var_pointee_volatile_flags 变量所指物 volatile(rawptr[t.CVolatile|T]) + # var_pointee_volatile_flags 变量所指物 volatile(rawptr[CVolatile|T]) # 模块级层(模块存活期持久): # global_* 模块级同名三类 # 类字段层(模块存活期持久): @@ -699,14 +699,14 @@ class BaseGenMixin: # 而非创建为 opaque 结构体(否则包含 Any 字段的结构体会变成 unsized)。 if clean_name == 'Any': return ir.IntType(8).as_pointer() - # t.CType 的基本类型子类(CInt/CChar/CSizeT/CLong/CFloat/CDouble 等, + # CType 的基本类型子类(CInt/CChar/CSizeT/CLong/CFloat/CDouble 等, # position 含 BASE 且 Size>0)有具体 LLVM 类型,应直接返回对应的 # ir.IntType/ir.FloatType/ir.DoubleType,而非创建结构体。 # _is_ctype_marker_name 对这些类型返回 False(不跳过),需要在此处拦截。 _basic_llvm_type: ir.Type | None = self._try_resolve_ctype_basic(clean_name) if _basic_llvm_type is not None: return _basic_llvm_type - # t.CType 及其子类是"类型强转"标记,不应被编译为真实结构体。 + # CType 及其子类是"类型强转"标记,不应被编译为真实结构体。 # 动态检查 t 模块中所有 CType 子类名(排除 CStruct/CEnum/CUnion/REnum 子类, # 因为用户定义的结构体类继承自它们,需要被创建为结构体)。 if self._is_ctype_marker_name(clean_name): @@ -718,12 +718,12 @@ class BaseGenMixin: # HandlesTypeMerge 的 Name/Attribute 分支、DeclarationGenerator 的 # `attr_name in struct_names` 同一条规则源): # _struct_sha1_map / class_sha1_map 已登记该名为**类**时,即便平坦符号表 - # 条目是**同名枚举成员**(如 ast/base.vp 的 `Constant: t.State` 与 + # 条目是**同名枚举成员**(如 ast/base.vp 的 `Constant: State` 与 # ast/exprs.vp 的 `class Constant` 同名;谁后插入谁占住裸名),也必须建成 # 结构体。否则此处返回 i32 ⇒ 上游 PtrCount=1 叠加后变成 i32*, # 与调用点实参 %".Constant"* 分裂(现场:constant_get_str_val 的 # 形参 i32*)。类型注解语境下枚举**成员**从不是类型,判据只能是"是否有类定义"。 - # 必须排除**枚举类型本身**(如 `class ASTKind(t.CEnum)`):_struct_sha1_map + # 必须排除**枚举类型本身**(如 `class ASTKind(CEnum)`):_struct_sha1_map # 是按 .vpi 里全部 ClassDef 建的,枚举类也在其中 —— 若一并当结构体,枚举 # 注解(kind() 返回值等)会被建为 opaque struct,引发 i32 ↔ 结构体错位 # ('IntType' object has no attribute 'is_opaque' 现场)。 @@ -880,7 +880,7 @@ class BaseGenMixin: pass return 0 # 标记为 typedef,但位宽为 0(非整数) - # t.CType 及其子类是"类型强转"标记,不应被创建为结构体。 + # CType 及其子类是"类型强转"标记,不应被创建为结构体。 # 动态检查 t 模块中所有 CType 子类名(排除 CStruct/CEnum/CUnion/REnum 子类)。 # 返回 0 标记为 typedef,使 _get_or_create_struct 走 typedef 路径返回 i8。 if self._is_ctype_marker_name(name): @@ -890,7 +890,7 @@ class BaseGenMixin: @staticmethod def _is_ctype_marker_name(name: str) -> bool: - """检查名称是否是 t.CType 的"类型强转"标记子类名。 + """检查名称是否是 CType 的"类型强转"标记子类名。 只有 position 不含 BASE 的纯修饰符/标记类型(CPtr/CVolatile/CConst/ CInline/CStatic/CExtern/CExport/CRegister/CAuto/_CTypedef/CTypeDefault 等) @@ -900,7 +900,7 @@ class BaseGenMixin: CStruct/CEnum/CUnion/REnum 的用户子类是合法结构体,需要被创建。 注意:CTypeRegistry.GetClassByName 会跳过 CType 本身和 CTypeDefault, - 所以这里直接用 getattr(t, name) 检查 t 模块属性。 + 所以这里直接用 getattr(TypeSystem, name) 检查 t 模块属性。 Returns: True 如果 name 是 CType 标记子类名(应跳过结构体创建) @@ -932,7 +932,7 @@ class BaseGenMixin: return True def _try_resolve_ctype_basic(self, name: str) -> ir.Type | None: - """尝试将 t.CType 的基本类型子类名解析为对应的 LLVM 基本类型。 + """尝试将 CType 的基本类型子类名解析为对应的 LLVM 基本类型。 仅对 t 模块内的 CType 基本类型子类(CInt/CChar/CSizeT/CLong/CFloat/ CDouble 等,即 position 含 BASE 且 Size>0)生效,返回对应的 @@ -1328,8 +1328,8 @@ class BaseGenMixin: (translator._line_offset = N);而 `Gen._current_source_lines` 是**磁盘** 原文 ⇒ 任何"AST 行号 + 源码行"的输出都必须先减 N,否则印出的源码是下一行。 本渲染器此前漏还原,于是同一次 fail-fast 里出现两套矛盾行号 - (现场:真实错误在 TypeGenResolve.vp:1141 `= "t.CPtr"`, - _get_node_info 印 1142 且源码取到 1142 行的 `return "t.CPtr"`, + (现场:真实错误在 TypeGenResolve.vp:1141 `= "CPtr"`, + _get_node_info 印 1142 且源码取到 1142 行的 `return "CPtr"`, 而 _ErrorStack 帧印的是正确的 1141/1140)。 """ if Lineno <= 0: @@ -1368,7 +1368,7 @@ class BaseGenMixin: 回退当前语句上下文(_get_node_info 风格),不再固定打印外层 Assign。 关键 ②:**行号必须先还原为磁盘行号**(_DiskLineno)——节点行号含文件头 自动注入 import 的偏移,直接用来读源码会读到下一行(现场:真实错误行 - 1141,这里印成 1142 且源码显示出 1142 行的 `return "t.CPtr"`)。 + 1141,这里印成 1142 且源码显示出 1142 行的 `return "CPtr"`)。 """ if Node is None: return self._get_node_info() @@ -1403,14 +1403,14 @@ class BaseGenMixin: """注解解析结果是否为「变量自身 const」的对象(C 语义下的 const 对象)。 判据(两侧统一):`(DataConst or VarConst)` 且 `PtrCount == 0`。 - `t.CConst` 在本仓库解析为 **DataConst**(t 模块分支:HandlesTypeMerge.py:192-196、 + `CConst` 在本仓库解析为 **DataConst**(t 模块分支:HandlesTypeMerge.py:192-196、 TypeAnnotationResolver.py:382-389),其字段语义是「指向的数据 const」 (HandlesBase.py:76-77)。因此: - 非指针类型(PtrCount==0):该限定退化为「该对象自身 const」⇒ - `a: const int` / `a: t.CConst | int` 的 a 禁止赋值/增量赋值/元素赋值; + `a: const int` / `a: CConst | int` 的 a 禁止赋值/增量赋值/元素赋值; - 指针类型(PtrCount>=1):限定只作用于 pointee ⇒ `const T *p` 的 p 仍可重新赋值(C 语义),**不**登记为 const 变量。 - 后者就是全仓既有两处 `t.CConst | T | t.CPtr` 局部变量(fat32_types.vp:1591 + 后者就是全仓既有两处 `CConst | T | CPtr` 局部变量(fat32_types.vp:1591 `buf_ptr`、elf.vp:509 `cmp_name`)在其作用域内被重新赋值却合法的原因。 """ if Info is None: @@ -1441,7 +1441,7 @@ class BaseGenMixin: @staticmethod def _AnnotationHasPointeeVolatile(Annotation: Any) -> bool: - """注解是否为 `rawptr[t.CVolatile | T]`(volatile 指针指向物,等价 C 的 volatile T*)。 + """注解是否为 `rawptr[CVolatile | T]`(volatile 指针指向物,等价 C 的 volatile T*)。 与 ViperC TypeGenErr.has_pointee_volatile_marker 同口径:只看 `rawptr[...]` 的下标实参子树里有没有 CVolatile;多级指针(slice 仍是 Subscript)明确不支持。 @@ -1463,7 +1463,7 @@ class BaseGenMixin: IsParam=True 时 **const 判据沿用形参的历史条件** `DataConst or VarConst` (不看指针层数):这是「形参保持现状 + 不得放宽任何既有 fail-fast」两条 硬约束下的唯一选择——把形参也改成指针感知判据虽然更合 C 语义,但会**放宽** - 既有形参检查(`fmt: t.CConst | str` 这类指针形参不再登记),从约束上不允许。 + 既有形参检查(`fmt: CConst | str` 这类指针形参不再登记),从约束上不允许。 该历史条件对 `const T*` 形参过严,但全仓 462 个 .vp 普查(见 Debugger/type-descriptors.md)表明**零个形参在其函数体内被重新赋值**, 故这处差异在既有代码上不可观测。非形参的三种声明一律用指针感知判据 @@ -1606,7 +1606,7 @@ class BaseGenMixin: return ( f"不能对 const 变量 '{Name}' {Kind}{self._get_node_info()}" f"(声明处类型(含 const):{DeclType};" - f"修法:删掉该声明里的 `const` 描述符 / `t.CConst`,或改为声明时一次赋值、" + f"修法:删掉该声明里的 `const` 描述符 / `CConst`,或改为声明时一次赋值、" f"之后只用非 const 的副本/中间量;const 对象在其作用域内禁止赋值、" f"增量赋值与元素赋值,且不会降级为警告)" ) diff --git a/lib/core/LLVMCG/ExprGen.py b/lib/core/LLVMCG/ExprGen.py index 203f8a6..aff99b6 100644 --- a/lib/core/LLVMCG/ExprGen.py +++ b/lib/core/LLVMCG/ExprGen.py @@ -183,7 +183,7 @@ class ExprGenMixin: # 见 HandlesExprOps / HandlesAugAssign)。此前这里又用 self._last_var_name # 判一次,而它只是“最近见过的变量名”,可能是**上一条表达式残留的别的变量**: # b: int64 = -196608 - # b >> 1 # 若残留名恰好是某个无符号变量(t.CSizeT 等) ⇒ 误判无符号 ⇒ lshr + # b >> 1 # 若残留名恰好是某个无符号变量(CSizeT 等) ⇒ 误判无符号 ⇒ lshr # 结果:负数右移变大正数(IntWidthTest Test 5/6 的 FAIL 即此)。 shift_ops: dict[str, Any] = { '>>': self.builder.lshr if is_unsigned else self.builder.ashr, @@ -197,7 +197,7 @@ class ExprGenMixin: } # 整数操作数宽度对齐:两个操作数都是整数但位宽不同时, # 统一扩展到较大位宽(低位宽操作数 zext/sext)。 - # 触发场景:`_g_alloc_count: t.CSizeT = 0`(i64 全局)在函数内 + # 触发场景:`_g_alloc_count: CSizeT = 0`(i64 全局)在函数内 # `_g_alloc_count += 1`,RHS 整数字面量是 i32,不扩展会报 # "Operands must be the same type, got (i64, i32)"。 if (op in ops or op in shift_ops or op in bit_ops or op in cmp_ops): @@ -340,7 +340,7 @@ class ExprGenMixin: from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转换已禁止({Reason}):函数 {self.func.name} 声明返回 {ret_type}," - f"但 return 的是指针类型 {value.type};如需转换请显式 cast(如 t.CPtr(...))" + f"但 return 的是指针类型 {value.type};如需转换请显式 cast(如 CPtr(...))" f"{self._DescribeValueNode(Node)}" ) value = self.builder.bitcast(value, ret_type, name="ret_cast") @@ -351,7 +351,7 @@ class ExprGenMixin: from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:函数 {self.func.name} 声明返回 {ret_type}," - f"但 return 的是指针类型 {value.type};如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"但 return 的是指针类型 {value.type};如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{self._DescribeValueNode(Node)}" ) elif isinstance(value.type.pointee, ret_type.__class__) and not isinstance(value.type.pointee, ir.IntType): @@ -364,7 +364,7 @@ class ExprGenMixin: from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:函数 {self.func.name} 声明返回 {ret_type}," - f"但 return 的是指针类型 {Loaded.type};如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"但 return 的是指针类型 {Loaded.type};如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{self._DescribeValueNode(Node)}" ) elif isinstance(ret_type, ir.IntType) and isinstance(value.type, ir.IntType): diff --git a/lib/core/LLVMCG/FuncGen.py b/lib/core/LLVMCG/FuncGen.py index 4b94098..f4bdd24 100644 --- a/lib/core/LLVMCG/FuncGen.py +++ b/lib/core/LLVMCG/FuncGen.py @@ -82,7 +82,7 @@ class FuncGenMixin: IsVtableSlot:该方法是否占用虚表槽(class_methods 即 vtable 槽序唯一真源)。 默认 True 与既有语义逐字一致;False 用于方法级 `novirtual def`(⇒ 方法装饰器 - @t.NoVTable)——此时只保证类的方法容器存在,**不**把它排进槽序,使 TPC 与 + @NoVTable)——此时只保证类的方法容器存在,**不**把它排进槽序,使 TPC 与 VPC(ClassGenBase._should_method_be_virtual 排除该项)的虚表布局逐槽相同。 """ if ClassName not in self.class_methods: @@ -109,7 +109,7 @@ class FuncGenMixin: - 'ref'(&T):实参已是指针 → 原样传;非指针左值 → 传该左值地址; 非指针且非左值(字面量/表达式结果)→ fail-fast(禁止静默降级)。 - 'temp'(&temp T):实参已是指针 → 原样传;否则在 entry 块建同型临时 + store + 传地址。 - - 'always'(t.CAutoPtr):无条件取址(保持既有语义)。 + - 'always'(CAutoPtr):无条件取址(保持既有语义)。 非指针左值的地址取自实参 load 指令的指针操作数(`load(p)` ⇒ p 即左值地址), 因为调用点实参已按 rvalue 求值(标量变量的 load 结果)。 @@ -149,11 +149,11 @@ class FuncGenMixin: return new_args def _adjust_args(self, args: list[ir.Value], func: ir.Function) -> list[ir.Value]: - # 自动取址(&T=ref / &temp T=temp / t.CAutoPtr=always)的**唯一汇聚点**: + # 自动取址(&T=ref / &temp T=temp / CAutoPtr=always)的**唯一汇聚点**: # 任何类型强转之前先做一次取址适配,于是 direct / vtable 虚分派 / 构造 / - # 静态方法 / __call__ / 下标赋值 / c.Addr 构造 / 闭包 / 泛型 / 方法兜底等 + # 静态方法 / __call__ / 下标赋值 / Addr 构造 / 闭包 / 泛型 / 方法兜底等 # **所有**调用路径都自动获得取址能力,无需在每个调用点手写。 - # 为什么只能在这里做:'always'(t.CAutoPtr)不幂等——它无条件 + # 为什么只能在这里做:'always'(CAutoPtr)不幂等——它无条件 # alloca+store+传地址,重复应用会把指针再包一层;原先散落在各调用点的 # 显式 Gen._apply_auto_addr(...) 与本汇聚点重复 ⇒ 已全部删除,由本处唯一负责。 # 查表键统一为**真实发射出的函数名** func.name(登记侧逐字写入同名键)。 @@ -237,7 +237,7 @@ class FuncGenMixin: raise FailFastError( f"指针隐式转换已禁止({Reason}):调用 {func.name} 第 {i} 个实参" f" {arg.type} 不能隐式转为形参 {param.type};如需转换请显式 cast" - f"(如 t.CPtr(...)){self._DescribeValueNode()}") + f"(如 CPtr(...)){self._DescribeValueNode()}") adjusted.append(self.builder.bitcast(arg, param.type, name=f"cast_arg_{i}")) else: if isinstance(arg.type, ir.PointerType) and isinstance(param.type, (ir.IdentifiedStructType, ir.LiteralStructType, ir.ArrayType)): @@ -345,9 +345,9 @@ class FuncGenMixin: 与 StructGen.py:442-450 的父链传播同源——vtable 沿继承链携带,子类 struct 布局为 [vtable?] + [基类字段…] + [自身字段…]。只认 class_vtable / - _cross_module_vtable_classes(装饰器集合)会漏掉源码未写 @t.CVTable 的跨模块 + _cross_module_vtable_classes(装饰器集合)会漏掉源码未写 @CVTable 的跨模块 AST 节点类(ast.Try / ast.Match / ast.ExceptHandler…):它们有方法、继承自 - @t.CVTable 的 AST,struct 首元素确实是 vtable 指针,但 StructGen.py:415 在 + @CVTable 的 AST,struct 首元素确实是 vtable 指针,但 StructGen.py:415 在 "struct body 已从 stub 完整加载"时直接 continue,永不把它们登记进集合 (实测 ViperC/temp/_shared_sym.json 的 class_vtable/cross_module_vtable 仅有 {AST, MemManager, Module})。此时 base 静默取 0 → 该类字段偏移整体前移 1 @@ -370,7 +370,7 @@ class FuncGenMixin: - 统一短名解析(治本修复 2026-08-10):struct/class_members/class_vtable/ class_parent 均以短名注册(跨模块加载 HandlesImports L1604),而调用方 可能传入带 sha1 前缀的全名(如 "f47f88ae6545965a.Import")。 - - rawptr[X] / t.CPtr[X] 指针包装归一:rawptr[X] 是内建裸指针类型 + - rawptr[X] / CPtr[X] 指针包装归一:rawptr[X] 是内建裸指针类型 (X*),非真实类——接收者注解/类型名为 'rawptr[AST]' 时字段访问 (child.parent)应作用于内层 struct X,否则查 class_members 全 miss → fast-fail "属性 'parent' 在类 'rawptr[AST]' 中找不到(struct=opaque)" @@ -379,7 +379,7 @@ class FuncGenMixin: if not ClassName: return ClassName _Cls: str = self._extract_short_name(ClassName) - if _Cls.startswith('rawptr[') or _Cls.startswith('t.CPtr['): + if _Cls.startswith('rawptr[') or _Cls.startswith('CPtr['): _lb: int = _Cls.find('[') if _Cls.endswith(']') and _lb > 0: _inner: str = _Cls[_lb + 1:-1].strip() @@ -411,7 +411,7 @@ class FuncGenMixin: 字段默认值、继承方法 this 调整等)都必须走本方法,禁止各自直查 `class_vtable`/`_cross_module_vtable_classes`——旧实现只认这两个装饰器集合, 跨模块 AST 节点类(ast.Try/ast.Match/ast.ExceptHandler…)源码未写 - @t.CVTable 且 StructGen 在"struct body 已从 stub 加载"时提前 continue, + @CVTable 且 StructGen 在"struct body 已从 stub 加载"时提前 continue, 永不把它们登记进集合,于是 base 只能靠"成员表长度 == struct 元素数 - 1" 这个长度启发式救回;成员表未展平/尚未加载时启发式失效 ⇒ base 静默取 0 ⇒ 该类所有字段偏移整体前移 1(ast.ExceptHandler.children 落到 @@ -517,10 +517,10 @@ class FuncGenMixin: # 【只在长度不齐(_Delta != 0)时校准】_Delta == 0 表示"成员表项数 == body # 槽数":定义端 body 由成员表生成、跨模块端 body(.stub.ll)与 .vpi 同源 # (同一声明顺序),长度相等即**逐位对齐**,base 必为 0。此时再用严格类型 - # 比较挑 b 反而会误判——声明侧的联合类型(如 `list[str] | t.CPtr`)可能被记成 + # 比较挑 b 反而会误判——声明侧的联合类型(如 `list[str] | CPtr`)可能被记成 # 折叠后的 i8*,而 body 槽仍是具体指针(`%list[str]*`):b=0 丢掉这些匹配, # 某个平移 b 却能靠指针槽互相撞分拿到更高分。 - # 现场(2026-09-30):TypeGenMixin(41 成员 / 41 槽 / @t.NoVTable,_Delta=0) + # 现场(2026-09-30):TypeGenMixin(41 成员 / 41 槽 / @NoVTable,_Delta=0) # base 被抬到 2 ⇒ `SubTypeGen.Gen = self`(Gen 声明 Generator*、正确槽 0) # 落到槽 40(TypeSpecArena*)⇒ "指针隐式转换已禁止(非基本类型(结构体/类/联合))"。 # _Delta != 0 的既有现场(ast.Constant 的 `cnst.lineno` 落到 pool 槽等)不受影响, @@ -631,7 +631,7 @@ class FuncGenMixin: # 此处检测冲突,加载正确模块的 class_members 并以 sha1 前缀全名缓存。 _ResolvedClass: str = ClassName if ClassName else '' if ClassName: - # 类键归一(短名 + rawptr[X]/t.CPtr[X] 展开)统一走 _NormalizeMemberClass, + # 类键归一(短名 + rawptr[X]/CPtr[X] 展开)统一走 _NormalizeMemberClass, # 与 _member_base 的 base 判定共用同一归一,禁止各写一份。 ClassName = self._NormalizeMemberClass(ClassName) _ResolvedClass = ClassName @@ -835,7 +835,7 @@ class FuncGenMixin: if (not _PairOk and isinstance(_mtEff, ir.PointerType) and isinstance(_etP, ir.PointerType)): # 联合类型字段在成员表里存成通用指针(如 AST.children = - # `list[rawptr[AST]] | t.CPtr` ⇒ i8*),而 body 槽是具体指针 + # `list[rawptr[AST]] | CPtr` ⇒ i8*),而 body 槽是具体指针 # (`%"...list[...]"*`):严格串比较会在这条**断链**,其后的 # 所有条目都不再消费槽位(cursor 不动)⇒ 目标字段全部退化成 # "base + 表内下标"(现场:ExceptHandler.name 表内下标 9 ⇒ diff --git a/lib/core/LLVMCG/MemoryOps.py b/lib/core/LLVMCG/MemoryOps.py index 4ffffcb..1c0ee26 100644 --- a/lib/core/LLVMCG/MemoryOps.py +++ b/lib/core/LLVMCG/MemoryOps.py @@ -182,7 +182,7 @@ class MemoryOpsMixin: @staticmethod def _IsGenericPtrType(typ: Any) -> bool: - """通用指针(t.CPtr / void*):指针链末端为 i8(i8* / i8** / ... 均算)。""" + """通用指针(CPtr / void*):指针链末端为 i8(i8* / i8** / ... 均算)。""" if not isinstance(typ, ir.PointerType): return False p: Any = typ.pointee @@ -274,18 +274,18 @@ class MemoryOpsMixin: """值节点是否为「显式指针 cast」调用(用户规则:显式转换一律放行)。 形式(TPC 解析产物的共同点 = ast.Call 且 func 是**指针类型表达式**): - - `t.CPtr(x)` / 别名 `CPtr(x)` / `c.CPtr(x)` - - `rawptr[T](x)` / `t.CPtr[T](x)` / 裸名 `CPtr[T](x)` + - `CPtr(x)` + - `rawptr[T](x)` / `CPtr[T](x)` / 裸名 `CPtr[T](x)` - `(T*)x` / `(T*)(x)` / `T*(x)`(含 `**` 两层;ExprParser 把三种写法统一 - 产成 Call(func = `T | t.CPtr`)) - - 裸 `rawptr(x)`(≡ t.CPtr) + 产成 Call(func = `T | CPtr`)) + - 裸 `rawptr(x)`(≡ CPtr) 非 cast 调用(构造函数 / 普通函数,如 `MemBuddy(x)`、`list[X](...)`)不命中 ⇒ 仍按隐式转换规则判定。只判 func 节点形状,不做类型解析(不与 Gen 耦合)。 - 必要性:`includes/_list.vp:60` 的 `elem_ptr: T | t.CPtr = t.CPtr(地址)` 在 - `list[X*]` 特化下 T | t.CPtr = `X**`(T 本身是指针),而 `t.CPtr(...)` 的值是 + 必要性:`includes/_list.vp:60` 的 `elem_ptr: T | CPtr = CPtr(地址)` 在 + `list[X*]` 特化下 T | CPtr = `X**`(T 本身是指针),而 `CPtr(...)` 的值是 `i8*`——层数不同被判"隐式转换已禁止",与报错自己给的"如需转换请显式 cast - (如 t.CPtr(...))"建议自相矛盾。显式 cast 一律放行后按 bitcast 重解释。 + (如 CPtr(...))"建议自相矛盾。显式 cast 一律放行后按 bitcast 重解释。 """ if not isinstance(Node, ast.Call): return False @@ -294,8 +294,6 @@ class MemoryOpsMixin: AnnotationContainsName) if IsCPtrNode(Func) or IsPtrSubscriptNode(Func): return True - if isinstance(Func, ast.Attribute) and Func.attr == 'CPtr': - return True if isinstance(Func, ast.Name) and Func.id in ('CPtr', 'rawptr'): return True if isinstance(Func, ast.BinOp) and isinstance(Func.op, ast.BitOr): @@ -307,7 +305,7 @@ class MemoryOpsMixin: """隐式转换判据:返回 (Allowed, Reason)。 规则(用户决定,与 ViperC 同口径): - ① 通用指针(t.CPtr/i8*)为通配:与任何 T* **双向**互转放行(须同级)。 + ① 通用指针(CPtr/i8*)为通配:与任何 T* **双向**互转放行(须同级)。 ② T* → U*(皆非通用):允许 ⇔ 被指类型 T → U 无损;非基本类型 (结构体/类/联合)一律不允许 ⇒ Foo*→Bar* 禁止;**例外**有二: 继承上转 Derived* → Base*(目标被指类型是源被指类型的基类,含多级) @@ -319,7 +317,7 @@ class MemoryOpsMixin: 由 _CtorCallStructType 单独放行(本判据只给出「禁」的结论)。 ④ 完全相同类型不算转换 ⇒ 放行。 ⑤ **显式 cast 一律放行**(用户规则「显式转换都可以」):值侧节点本身是写明的 - 指针转换调用(t.CPtr(x) / rawptr[T](x) / (T*)x ...,见 + 指针转换调用(CPtr(x) / rawptr[T](x) / (T*)x ...,见 _IsExplicitPtrCastNode)⇒ 目标类型即程序员指定的转换目标,调用方按 bitcast 重解释,不做层数/被指类型判定。 Reason 供报文说明「哪一级不允许 + 原因(非基本类型/有损/层数不同)」。 @@ -667,7 +665,7 @@ class MemoryOpsMixin: from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"隐式窄化禁止:{val.type.width} 位整数不能隐式赋给 {target_type.width} 位类型" - f"(会丢高位);请显式转换(如 int32(x) / t.CInt32T(x))或把目标类型加宽" + f"(会丢高位);请显式转换(如 int32(x) / CInt32T(x))或把目标类型加宽" f"{self._DescribeValueNode(Node)}" ) elif val.type.width == 1: @@ -686,7 +684,7 @@ class MemoryOpsMixin: from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转换已禁止({Reason}):不能把指针类型 {val.type} 隐式转为 {target_type};" - f"如需转换请显式 cast(如 t.CPtr(...))" + f"如需转换请显式 cast(如 CPtr(...))" f"{self._DescribeValueNode(Node)}" ) return self.builder.bitcast(val, target_type, name="ptr_bitcast_store") @@ -702,7 +700,7 @@ class MemoryOpsMixin: from lib.core.LLVMCG.FuncGen import FailFastError raise FailFastError( f"指针隐式转整数已禁止:不能把指针类型 {val.type} 赋给整数类型 {target_type};" - f"如需转换请显式 cast(如 t.CUInt64T(p) / t.CInt(p))" + f"如需转换请显式 cast(如 CUInt64T(p) / CInt(p))" f"{self._DescribeValueNode(Node)}" ) if isinstance(target_type, ir.FloatType) and isinstance(val.type, ir.DoubleType): @@ -730,7 +728,7 @@ class MemoryOpsMixin: if isinstance(val.type, ir.PointerType) and not isinstance(target_type, ir.PointerType): # 规则③:非基本类型 T 与 T* 之间的隐式转换(Foo ↔ Foo*)一律禁止—— # 指针→非指针值的隐式 load(结构体/数组按值回读)属类型信息缺失, - # 须显式解引用(c.Deref(p) / *p)或显式强转。基本标量目标已在上方 + # 须显式解引用(Deref(p) / *p)或显式强转。基本标量目标已在上方 # 「指针隐式转整数」分支 fail-fast,此处只兜非基本类型。 # **唯一例外=「构造物化」**:右值来自该类型的构造调用时放行,如 # `p: Point = Point()`、`*slot = LLVMType.Struct(...)`(参照 GCC 构造 @@ -746,7 +744,7 @@ class MemoryOpsMixin: raise FailFastError( f"非基本类型的值/指针隐式转换已禁止(构造物化除外,{Reason3}):" f"不能把指针类型 {val.type} 隐式转为值类型 {target_type};" - f"如需解引用请显式 c.Deref(p) / *p,或显式强转" + f"如需解引用请显式 Deref(p) / *p,或显式强转" f"{self._DescribeValueNode(Node)}" ) if val.type.pointee == target_type: diff --git a/lib/core/LLVMCG/StructGen.py b/lib/core/LLVMCG/StructGen.py index b714b1a..ebc34df 100644 --- a/lib/core/LLVMCG/StructGen.py +++ b/lib/core/LLVMCG/StructGen.py @@ -4,7 +4,7 @@ import re import vast as ast import llvmlite.ir as ir from llvmlite.ir.values import _Undefined -from lib.includes import t as _t +from lib.core import TypeSystem as _t from lib.core.VLogger import get_logger as _vlog # vtable 槽类型 `i8*` 的共享实例:llvmlite 的类型是不可变值语义(`_TypedPointerType` @@ -305,100 +305,100 @@ class StructGenMixin: return ir_text - def _MemberSlotAccepts(self, Declared: Any, Slot: Any) -> bool: - """声明类型能否**隐式写进**该 struct 槽(判据与存储侧同一套)。 - - 用于判定已冻结的 struct body 是否与 `class_members` 自洽。判定放宽到与 - 存储侧一致,避免误清:通用指针槽(i8*/void*)照旧放行(历史 stub 普遍 - 如此),继承上转/数组退让亦放行;只有**存储时必被拒绝**的组合——层数 - 不同、指针与非指针混位——才判为不一致,触发重建。 - """ - if Declared is None or Slot is None: - return True - # 同一对象直接放行:llvmlite 的 Type.__eq__ 走类型键比较(profile: - # 本函数被 _generate_structs 调 54.2M 次,其中 types.py __eq__ 合计 ~30s) - # ⇒ 先做身份判定短路,等价且避免绝大多数 __eq__/str() 开销。 - if Declared is Slot: - return True - if Declared == Slot or str(Declared) == str(Slot): - return True - _d_ptr: bool = isinstance(Declared, ir.PointerType) - _s_ptr: bool = isinstance(Slot, ir.PointerType) - if _d_ptr != _s_ptr: - return False - if not _d_ptr: - # 数值/浮点宽度差异不在本次收紧范围:保持既有行为(不清 body)。 - return True - try: - Allowed, _Reason = self._ClassifyPtrImplicitConvert(Declared, Slot) - return bool(Allowed) - except Exception: - # 判据不可用(缺上下文)时保守放行,避免误清已正确的布局。 - return True - - def _IsRenumLayoutClass(self, ClassName: str | None) -> bool: - """该类是否属 **REnum 布局**(主 REnum 自身,或其变体嵌套结构体 `_`)。 - - REnum 的 struct body 是 **max-variant 镜像布局**:`class_members` 里那些名字是 - *变体*(不是字段),变体嵌套结构体也必须逐字镜像主结构体。因此**一律不得**用 - class_members 的"声明类型"去改写或校验它们的布局 —— 否则跨模块 GEP 偏移与 - 定义端失配(变体载荷槽本就允许与 max-variant 槽类型不同,取值处靠 bitcast)。 - """ - if not ClassName: - return False - _tbl: Any = getattr(self, 'SymbolTable', None) - if _tbl is None: - return False - try: - _e: Any = _tbl.lookup(ClassName) - except Exception: - return False - if _e is not None and getattr(_e, 'IsRenum', False): - return True - if '_' in ClassName: - _prefix: str = ClassName.rsplit('_', 1)[0] - try: - _pe: Any = _tbl.lookup(_prefix) - except Exception: - _pe = None - if _pe is not None and getattr(_pe, 'IsRenum', False): - return True - return False - - def _StructBodyHasPlaceholderT(self, St: Any) -> bool: - """该 struct body 是否含未特化的 `T*` 占位字段(结果按 body 对象记忆)。 - - `_generate_structs` 里有两处对"全部类的全部元素"做这一扫描(Step 4 的完整性与 - set_body 前的复核),每次调用都全量重扫 —— profile(2026-09-29 main_prof_72472): - 这两处是本函数 62.5M 次 `isinstance`(6.20s)与 4.98M 次 `rsplit`(1.12s)的主源。 - - 判定精确性:扫描是 `st.elements` 的**纯函数**,而 `elements` 在 llvmlite 里是 - **整体替换**(`set_body` 赋新 tuple;作废时置 None;从不原地改元素)⇒ 用 - `elements` 的**对象身份**当版本号即可精确判定"body 未变"。缓存条目**强引用** - struct 实例与 elements 对象,二者存活 ⇒ `id()` 不会被回收复用 ⇒ 不会误判命中。 - (代价:被替换掉的旧 body tuple 会被缓存多留一份引用;量级 = 结构体数量级,可忽略。) - """ - _cache: dict | None = getattr(self, '_struct_t_placeholder_cache', None) - if _cache is None: - _cache = {} - self._struct_t_placeholder_cache = _cache - _key: int = id(St) - _elems: Any = getattr(St, 'elements', None) - _hit: Any = _cache.get(_key) - if _hit is not None and _hit[0] is St and _hit[1] is _elems: - return _hit[2] - _found: bool = False - if _elems: - for _elem in _elems: - if isinstance(_elem, ir.PointerType) and isinstance(_elem.pointee, ir.IdentifiedStructType): - _pname: str = _elem.pointee.name - _short: str = _pname.rsplit('.', 1)[-1] if '.' in _pname else _pname - if _short == 'T': - _found = True - break - _cache[_key] = (St, _elems, _found) - return _found - + def _MemberSlotAccepts(self, Declared: Any, Slot: Any) -> bool: + """声明类型能否**隐式写进**该 struct 槽(判据与存储侧同一套)。 + + 用于判定已冻结的 struct body 是否与 `class_members` 自洽。判定放宽到与 + 存储侧一致,避免误清:通用指针槽(i8*/void*)照旧放行(历史 stub 普遍 + 如此),继承上转/数组退让亦放行;只有**存储时必被拒绝**的组合——层数 + 不同、指针与非指针混位——才判为不一致,触发重建。 + """ + if Declared is None or Slot is None: + return True + # 同一对象直接放行:llvmlite 的 Type.__eq__ 走类型键比较(profile: + # 本函数被 _generate_structs 调 54.2M 次,其中 types.py __eq__ 合计 ~30s) + # ⇒ 先做身份判定短路,等价且避免绝大多数 __eq__/str() 开销。 + if Declared is Slot: + return True + if Declared == Slot or str(Declared) == str(Slot): + return True + _d_ptr: bool = isinstance(Declared, ir.PointerType) + _s_ptr: bool = isinstance(Slot, ir.PointerType) + if _d_ptr != _s_ptr: + return False + if not _d_ptr: + # 数值/浮点宽度差异不在本次收紧范围:保持既有行为(不清 body)。 + return True + try: + Allowed, _Reason = self._ClassifyPtrImplicitConvert(Declared, Slot) + return bool(Allowed) + except Exception: + # 判据不可用(缺上下文)时保守放行,避免误清已正确的布局。 + return True + + def _IsRenumLayoutClass(self, ClassName: str | None) -> bool: + """该类是否属 **REnum 布局**(主 REnum 自身,或其变体嵌套结构体 `_`)。 + + REnum 的 struct body 是 **max-variant 镜像布局**:`class_members` 里那些名字是 + *变体*(不是字段),变体嵌套结构体也必须逐字镜像主结构体。因此**一律不得**用 + class_members 的"声明类型"去改写或校验它们的布局 —— 否则跨模块 GEP 偏移与 + 定义端失配(变体载荷槽本就允许与 max-variant 槽类型不同,取值处靠 bitcast)。 + """ + if not ClassName: + return False + _tbl: Any = getattr(self, 'SymbolTable', None) + if _tbl is None: + return False + try: + _e: Any = _tbl.lookup(ClassName) + except Exception: + return False + if _e is not None and getattr(_e, 'IsRenum', False): + return True + if '_' in ClassName: + _prefix: str = ClassName.rsplit('_', 1)[0] + try: + _pe: Any = _tbl.lookup(_prefix) + except Exception: + _pe = None + if _pe is not None and getattr(_pe, 'IsRenum', False): + return True + return False + + def _StructBodyHasPlaceholderT(self, St: Any) -> bool: + """该 struct body 是否含未特化的 `T*` 占位字段(结果按 body 对象记忆)。 + + `_generate_structs` 里有两处对"全部类的全部元素"做这一扫描(Step 4 的完整性与 + set_body 前的复核),每次调用都全量重扫 —— profile(2026-09-29 main_prof_72472): + 这两处是本函数 62.5M 次 `isinstance`(6.20s)与 4.98M 次 `rsplit`(1.12s)的主源。 + + 判定精确性:扫描是 `st.elements` 的**纯函数**,而 `elements` 在 llvmlite 里是 + **整体替换**(`set_body` 赋新 tuple;作废时置 None;从不原地改元素)⇒ 用 + `elements` 的**对象身份**当版本号即可精确判定"body 未变"。缓存条目**强引用** + struct 实例与 elements 对象,二者存活 ⇒ `id()` 不会被回收复用 ⇒ 不会误判命中。 + (代价:被替换掉的旧 body tuple 会被缓存多留一份引用;量级 = 结构体数量级,可忽略。) + """ + _cache: dict | None = getattr(self, '_struct_t_placeholder_cache', None) + if _cache is None: + _cache = {} + self._struct_t_placeholder_cache = _cache + _key: int = id(St) + _elems: Any = getattr(St, 'elements', None) + _hit: Any = _cache.get(_key) + if _hit is not None and _hit[0] is St and _hit[1] is _elems: + return _hit[2] + _found: bool = False + if _elems: + for _elem in _elems: + if isinstance(_elem, ir.PointerType) and isinstance(_elem.pointee, ir.IdentifiedStructType): + _pname: str = _elem.pointee.name + _short: str = _pname.rsplit('.', 1)[-1] if '.' in _pname else _pname + if _short == 'T': + _found = True + break + _cache[_key] = (St, _elems, _found) + return _found + def _generate_structs(self) -> None: # 热路径局部化:profile 中本函数被调 35,240 次(cum 1893s),内部 # SymbolTable.lookup 15.9M 次(16.7s)+ 真值判断触发的 __len__ 15.9M 次 @@ -569,7 +569,7 @@ class StructGenMixin: # 治本修复:检查 struct body 是否不完整(元素数少于 class_members + vtable 预期)。 # 常见于跨模块继承:子类 struct 在父类 class_members 加载前从 stub 生成, # stub 中的定义可能不完整或类型不正确(如 GSList* 代替 AST*、i8* 代替 i32)。 - # 此处检测到不完整后清除 elements(公开属性,见下方 Step 4 说明)和 + # 此处检测到不完整后清除 elements(公开属性,见下方 Step 4 说明)和 # stub 缓存,让后续代码重新从 stub 加载。 _has_vtable_precheck: bool = ClassName in self.class_vtable or ClassName in self._cross_module_vtable_classes if not _has_vtable_precheck: @@ -774,7 +774,7 @@ class StructGenMixin: # 优先从 stub.ll 加载完整定义。set_body 只能对 opaque struct 调用一次, # 若用不完整 class_members 设置 body,后续无法修正,会导致 GEP 越界。 # 但本地定义的类(_classes_in_progress)不从 stub 加载,因为 stub 可能 - # 来自同名导入类,其 vtable 状态与本地定义不同(@t.NoVTable 冲突) + # 来自同名导入类,其 vtable 状态与本地定义不同(@NoVTable 冲突) import_handler: Any = self._import_handler_ref if import_handler is not None and ClassName not in self._classes_in_progress: try: @@ -924,7 +924,7 @@ class StructGenMixin: needs_fix = True elif isinstance(gv.initializer, ir.Constant): if isinstance(gv.initializer.constant, list): - if any(hasattr(c, 'constant') and isinstance(c.constant, _Undefined) for c in gv.initializer.constant): + if any(hasattr(c, 'constant') and isinstance(constant, _Undefined) for c in gv.initializer.constant): needs_fix = True if not needs_fix: continue diff --git a/lib/core/LLVMCG/TypeConvert.py b/lib/core/LLVMCG/TypeConvert.py index 86e8328..fda59f5 100644 --- a/lib/core/LLVMCG/TypeConvert.py +++ b/lib/core/LLVMCG/TypeConvert.py @@ -4,13 +4,11 @@ import vast as ast import re import logging import llvmlite.ir as ir -from lib.includes import t as _t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem as _t +from lib.core.TypeSystem import CTypeRegistry from lib.core.Handles.HandlesBase import CTypeInfo as _CTypeInfo, BuiltinTypeMap from lib.constants.config import mode as _config_mode from lib.core.VLogger import get_logger as _vlog -from lib.core.SymbolUtils import IsTModule - # `_type_str_to_llvm_impl` / `_type_str_to_llvm_base` 解析类型字符串用的**预编译**正则 # (性能:类型字符串解析在热路径上频繁调用,字面量正则预编译避免 re 缓存查找与编译开销)。 _RE_ARRAY_DIM: re.Pattern[str] = re.compile(r'\[(\d+)\]') @@ -73,7 +71,7 @@ class TypeConvertMixin: return _enum_result # REnum 类型:通过 Name 查找或创建结构体(BaseType 可能为 None) - # 这对 BinOp `LLVMType | t.CPtr` 合并后的 CTypeInfo 至关重要 + # 这对 BinOp `LLVMType | CPtr` 合并后的 CTypeInfo 至关重要 if type_info.IsRenum and type_info.Name: if type_info.Name in self.structs: base: ir.Type = self.structs[type_info.Name] @@ -220,9 +218,6 @@ class TypeConvertMixin: if len(parts) < 2: return None module_name: str = parts[0] - # 跳过 t/c 等内建模块 - if module_name in {'t', 'c'}: - return None # 从 ModuleSha1Map 查找 SHA1(支持完整路径名和短名) sha1_map: dict[str, str] = getattr(self, 'ModuleSha1Map', {}) source_sha1: str | None = sha1_map.get(module_name) @@ -351,8 +346,8 @@ class TypeConvertMixin: type_str = type_str[:-1].strip() if ptr_depth > 0: IsPtr = True - # [builtins 最后匹配] typedef 下标字符串(rawptr[AST] / t.CPtr[AST]): - # base 为 builtins 指针 typedef(rawptr → t.CPtr)时等价"指向切片类型", + # [builtins 最后匹配] typedef 下标字符串(rawptr[AST] / CPtr[AST]): + # base 为 builtins 指针 typedef(rawptr → CPtr)时等价"指向切片类型", # 直接转 arg*,防止 stub/ToString 字符串化产物被误建为 'rawptr[AST]' # phantom 结构体(class_members 为空 → 属性访问 fail-fast KeyError)。 _sub_m: re.Match | None = _RE_SUBSCRIPT_TYPE.fullmatch(type_str) @@ -366,7 +361,7 @@ class TypeConvertMixin: _is_ptr_td = True except Exception: _is_ptr_td = False - if not _is_ptr_td and _sub_base in ('CPtr', 't.CPtr', 'c.CPtr'): + if not _is_ptr_td and _sub_base in ('CPtr', 'CPtr', 'CPtr'): _is_ptr_td = True if _is_ptr_td and _sub_arg: _sub_inner: ir.Type = self._type_str_to_llvm(_sub_arg, True) @@ -461,7 +456,7 @@ class TypeConvertMixin: # 文件无需 import 即用):未注册进当前模块 SymbolTable → 常规路径 miss 后 # 落 unknown 被建 %{mod}.int64 opaque → "TypeError: i64 != %int64*" # (ClassGenGeneric._clone_annotation / ast.Constant.__new__ int_val 根因)。 - # 按 builtins.vp 权威定义(int64 → t.CInt64T → i64)展开。 + # 按 builtins.vp 权威定义(int64 → CInt64T → i64)展开。 try: from lib.core.TypeAnnotationResolver import TypeAnnotationResolver as _TAR3 _builtin_val_tc: str | None = _TAR3.builtins_typedef_value(type_str) @@ -497,7 +492,7 @@ class TypeConvertMixin: return opaque if _Entry and _Entry.IsStruct: # 结构体类型(来自 _InsertClassSymbol):必须返回结构体类型而非 i32, - # 否则 (ast.Import | t.CPtr) 联合转换会得到 i32* 导致字段访问 GEP 偏移错误 + # 否则 (ast.Import | CPtr) 联合转换会得到 i32* 导致字段访问 GEP 偏移错误 if type_str in self.structs: if IsPtr: return ir.PointerType(self.structs[type_str]) @@ -653,7 +648,7 @@ class TypeConvertMixin: # 未知类型:可能是跨模块结构体(如 'Import' 来自 ast 模块)。 # 尝试通过 _get_or_create_struct 创建/查找结构体, # 该方法内部会检查 typedef/enum 等并返回正确类型。 - # 必须在 fallback 到 i32 之前执行,否则 (ast.Import | t.CPtr) 联合转换 + # 必须在 fallback 到 i32 之前执行,否则 (ast.Import | CPtr) 联合转换 # 会得到 i32* 导致字段访问 GEP 偏移错误(AccessViolation 崩溃)。 _cand_sha1: str | None = self._get_source_sha1_from_type_str(type_str) candidate: ir.Type = self._get_or_create_struct(type_str, source_sha1=_cand_sha1) @@ -782,8 +777,8 @@ class TypeConvertMixin: # 直接调用: rdrand64() func_name = func_node.id elif isinstance(func_node, ast.Attribute): - # t.CUInt64T(x) 等类型转换调用 - if hasattr(func_node.value, 'id') and IsTModule(func_node.value.id, self.SymbolTable): + # CUInt64T(x) 等类型转换调用 + if hasattr(func_node.value, 'id') : if self._is_type_unsigned(func_node.attr): return True # module.func() 形式的调用 diff --git a/lib/core/LLVMTypeMapper.py b/lib/core/LLVMTypeMapper.py index e3aa092..13d428e 100644 --- a/lib/core/LLVMTypeMapper.py +++ b/lib/core/LLVMTypeMapper.py @@ -19,17 +19,17 @@ if TYPE_CHECKING: from lib.core.Handles.HandlesBase import CTypeInfo, CTypeHelper, BuiltinTypeMap from lib.core.SymbolUtils import ( - IsTModule, IsListAnnotation, IsCPtrNode, IsCPtrSubscriptNode, + IsListAnnotation, IsCPtrNode, IsCPtrSubscriptNode, IsRawPtrSubscriptNode, EnumIntWidth, ResolveGenericClassSpecName, GetStructSha1MapFromSymtab, GetTCAliasMapFromSymtab) -from lib.includes import t as _t -from lib.includes.t import CTypeRegistry +from lib.core import TypeSystem as _t +from lib.core.TypeSystem import CTypeRegistry # typedef 值位置的类型限定符标记:它们自身不是类型(名下有 const/volatile 语义, # 由注解解析器累积),在 typedef 值里只修饰 `|` 另一侧。历史写法 -# `t.CConst | char | t.CPtr` 恰好被 `char` 一侧掩盖;新语法 `const str` -# (= `t.CConst | str`)暴露了这一点,故显式判为"无类型信息"。 +# `CConst | char | CPtr` 恰好被 `char` 一侧掩盖;新语法 `const str` +# (= `CConst | str`)暴露了这一点,故显式判为"无类型信息"。 _TYPEDEF_VALUE_QUALIFIERS: frozenset[str] = frozenset({'CConst', 'CVolatile'}) @@ -59,7 +59,7 @@ class LLVMTypeMapper: def __init__(self, symtab: SymbolTable): self._symtab = symtab # 本模块声明的类型名(由 TypeResolver.resolve 注入)。函数签名里的裸类引用 - # (rawptr[X] / X / t.CPtr[X])依赖它解析成类指针:缺了它,X 落到 + # (rawptr[X] / X / CPtr[X])依赖它解析成类指针:缺了它,X 落到 # _resolve_name 的解析失败分支,rawptr[X] 会退化成 i32*(类信息丢失)。 self._ClassNames: set[str] = set() # 本模块枚举名 → 存储位宽(bit);按登记的宽度物化(默认 32,与改前同值) @@ -143,7 +143,7 @@ class LLVMTypeMapper: if returns_node is None: return 'i32' if isinstance(returns_node, ast.BinOp) and isinstance(returns_node.op, ast.BitOr): - # 统一走 CPtr 感知的联合解析(int | t.CPtr → i32*、str | t.CPtr → i8**) + # 统一走 CPtr 感知的联合解析(int | CPtr → i32*、str | CPtr → i8**) return self._resolve_bitor(returns_node) result: str = self.get_llvm_type_str(returns_node) return result if result else 'i32' @@ -153,7 +153,7 @@ class LLVMTypeMapper: 末尾的「不许静默变 i32」守卫:`Subscript` / 联合(`|`)形态的形参注解若解析结果 是 `'i32'`,只可能是**解析失败后的兜底** —— 合法的下标注解是容器 / 泛型 / 定长数组 - (解析出指针、数组或结构体指针),合法的联合写法是 `T | t.CPtr` 这类指针叠加,都 + (解析出指针、数组或结构体指针),合法的联合写法是 `T | CPtr` 这类指针叠加,都 不会是 i32。该串会被 `_InsertFuncSymbol` 原样存进符号表(`FuncPtrParams`),再由 `BuildLLVMFuncTypeFromSig` 物化成形参类型 —— 一旦是 i32,调用点就在 `_adjust_args` 报「实参 %X* 不能隐式转为 i32」,把真因(**注解没解析出来**)掩盖成"调用点类型 @@ -193,7 +193,7 @@ class LLVMTypeMapper: # 短别名 / 内建速记(char/int/int64/uchar/str…):与注解位置 # `_resolve_name` 同源。缺此分支时 typedef 值里的裸名解析为空, # 整条 typedef 随之解析失败(现场:w32/win32base.vp 的 - # `LPCSTR: t.CTypedef = t.CConst | char | t.CPtr` ⇒ LPCSTR 不登记, + # `LPCSTR: CTypedef = CConst | char | CPtr` ⇒ LPCSTR 不登记, # 用到处报「裸名 LPCSTR 无法解析为类型」)。 _binfo: CTypeInfo | None = self._lookup_builtins_typedef(node.id) if _binfo is None: @@ -211,14 +211,14 @@ class LLVMTypeMapper: return _nm + (' *' * (_binfo.PtrCount or 0)) return '' if isinstance(node, ast.Attribute): - if isinstance(node.value, ast.Name) and IsTModule(node.value.id): + if isinstance(node.value, ast.Name) : # 直接判断属性名是否为 CPtr(消除对 CName=='*' 的依赖) if node.attr == 'CPtr': return 'ptr' if node.attr in _TYPEDEF_VALUE_QUALIFIERS: # 类型限定符标记(const/volatile)本身不是类型:它只修饰 `|` 另一侧。 - # 旧写法 `t.CConst | char | t.CPtr` 靠 char 一侧掩盖了这一点;一旦写成 - # `t.CConst | str`(`const str`),把 'CConst' 当基类型会得到 'CConst *', + # 旧写法 `CConst | char | CPtr` 靠 char 一侧掩盖了这一点;一旦写成 + # `CConst | str`(`const str`),把 'CConst' 当基类型会得到 'CConst *', # 于是别名登记失败、所有使用处报「裸名 … 无法解析为类型」。 return '' CName: str | None = CTypeHelper.GetCName(node.attr) @@ -356,10 +356,10 @@ class LLVMTypeMapper: # --- 同名冲突:平坦条目被 define / 枚举成员 / 函数占位时找回类型 ---- # 平坦表(无前缀)一个名字只能留一个条目,而不同模块可能用**不同类型种类** # 声明同名符号(谁后插入谁占住裸名),两个真实例子: - # · stdint.vp:9 `INT: t.CTypedef = t.CInt` vs argparse.vp:33 - # `define INT = 1`(sig 里是 `INT: t.CDefine = 1`)—— 注解 `oflag: INT` + # · stdint.vp:9 `INT: CTypedef = CInt` vs argparse.vp:33 + # `define INT = 1`(sig 里是 `INT: CDefine = 1`)—— 注解 `oflag: INT` # · llvmlite/__function.vp:77 `class Function` vs ast/tokens.vp:95 - # 枚举成员 `Function: t.State` —— 注解 `func: rawptr[Function]` + # 枚举成员 `Function: State` —— 注解 `func: rawptr[Function]` # 注解位置只可能是 typedef / 类 / 枚举 ⇒ 平坦条目不是这三种时,跨命名空间 # (各模块的声明登记在 _namespaces[模块名] 下)再找同名条目。 _cand_sym: CTypeInfo | None @@ -390,7 +390,7 @@ class LLVMTypeMapper: # (`CInt | CExport` → i32)。与 _resolve_attribute 的 marker 分支、 # TypeAnnotationResolver._ResolveNameNode 的 STORAGE_CLASS/TYPE_QUALIFIER # 判定同口径。缺此分支时裸名标记会落到下方 fail-fast —— 而带前缀写作 - # `t.CExport` 时却能通过(走 Attribute 路径),同一语义两种写法结果不同。 + # `CExport` 时却能通过(走 Attribute 路径),同一语义两种写法结果不同。 # 现场:Test/AstTest `def main() -> CInt | CExport`(第 108 行)。 _marker_cls: object = getattr(_t, node.id, None) if (isinstance(_marker_cls, type) and _marker_cls is not _t.CType @@ -450,11 +450,11 @@ class LLVMTypeMapper: if elem_types: return '{ ' + ', '.join(elem_types) + ' }' if IsCPtrSubscriptNode(node): - # t.CPtr[T] → Ptr(resolve(T))(对齐 VPC Subscript 分支 + # CPtr[T] → Ptr(resolve(T))(对齐 VPC Subscript 分支 # TypeGenResolve.vp:2769-2790;void 首层归一化为 i8*) return self._add_pointer_level(self.get_llvm_type_str(node.slice)) if IsRawPtrSubscriptNode(node): - # rawptr[T](内置裸指针下标)≡ `T | t.CPtr`:与定义端 TypeMerge 的 + # rawptr[T](内置裸指针下标)≡ `T | CPtr`:与定义端 TypeMerge 的 # 合并语义同口径(裸类引用自身即指针,吸收这一层;其余逐层外包)。 # 此前只认 IsCPtrSubscriptNode → rawptr[T] 落到下方 warn 并退化成 i32。 return self._rawptr_subscript_type_str(node) @@ -486,14 +486,14 @@ class LLVMTypeMapper: def _resolve_bitor(self, node: ast.BinOp) -> str: """解析 ast.BinOp(BitOr) 节点(CPtr 感知的指针层级叠加)。 - T | t.CPtr 一侧为 t.CPtr 标记时,另一侧追加一层 '*': - int | t.CPtr → i32* (原逻辑误降级为 i8*) - str | t.CPtr → i8** (原逻辑误降级为 i8*) - (int | t.CPtr) | t.CPtr → i32**(嵌套递归叠加) - T | t.CPtr[...] 一侧为下标指针类型时,另一侧叠加该下标的指针层级 N + T | CPtr 一侧为 CPtr 标记时,另一侧追加一层 '*': + int | CPtr → i32* (原逻辑误降级为 i8*) + str | CPtr → i8** (原逻辑误降级为 i8*) + (int | CPtr) | CPtr → i32**(嵌套递归叠加) + T | CPtr[...] 一侧为下标指针类型时,另一侧叠加该下标的指针层级 N (N = 1 + 切片自身层数,不含 struct 吸收,对齐 VPC BinOp 下标分支 TypeGenResolve.vp:2596-2639): - t.CUInt8T | t.CPtr[t.CPtr] → i8**(原逻辑误降级为首段 i8) + CUInt8T | CPtr[CPtr] → i8**(原逻辑误降级为首段 i8) """ left: str = self.get_llvm_type_str(node.left) right: str = self.get_llvm_type_str(node.right) @@ -503,7 +503,7 @@ class LLVMTypeMapper: return self._add_pointer_level(left) if left_is_cptr: return self._add_pointer_level(right) - # t.CPtr[...] 下标指针标记:X | t.CPtr[...] → Ptr^N(X) + # CPtr[...] 下标指针标记:X | CPtr[...] → Ptr^N(X) if IsCPtrSubscriptNode(node.right): return self._add_pointer_levels(left, self._cptr_subscript_ptr_level(node.right)) if IsCPtrSubscriptNode(node.left): @@ -531,9 +531,9 @@ class LLVMTypeMapper: def _rawptr_subscript_type_str(self, node: ast.Subscript) -> str: """rawptr[T](内置裸指针下标)→ LLVM 类型串。 - 与定义端同口径(`T | t.CPtr` 的合并):裸类引用('%struct.X*' / + 与定义端同口径(`T | CPtr` 的合并):裸类引用('%struct.X*' / '%"sha1.X"*' / 泛型特化等以 '%' 开头的结构指针)自身即指针,吸收这一层; - 其余(标量、已是指针的 typedef、联合写法、嵌套 rawptr / t.CPtr 下标) + 其余(标量、已是指针的 typedef、联合写法、嵌套 rawptr / CPtr 下标) 逐层外包(void → i8*)。 """ inner: ast.AST = node.slice @@ -553,10 +553,10 @@ class LLVMTypeMapper: return result def _cptr_subscript_ptr_level(self, node: ast.AST) -> int: - """t.CPtr[T] 下标指针标记贡献的指针层级 N(= 1 + 切片自身层数)。 + """CPtr[T] 下标指针标记贡献的指针层级 N(= 1 + 切片自身层数)。 复用定义侧解析器 TypeAnnotationResolver.from_node(其 _from_node_subscript - 已实现 t.CPtr[T] → Ptr(T) 的层级叠加,见 TypeAnnotationResolver.py:756-783), + 已实现 CPtr[T] → Ptr(T) 的层级叠加,见 TypeAnnotationResolver.py:756-783), 与 HandlesTypeMerge._HandleSubscript(HandlesTypeMerge.py:512-531)同口径。 调用前须经 IsCPtrSubscriptNode 判据过滤,故 PtrCount 至少为 1。 """ @@ -565,8 +565,7 @@ class LLVMTypeMapper: def _resolve_call(self, node: ast.Call) -> str: """解析 ast.Call 节点""" - if isinstance(node.func, ast.Attribute): - if hasattr(node.func.value, 'id') and IsTModule(node.func.value.id): - return self.get_llvm_type_str(ast.Attribute(value=ast.Name(id='t'), attr=node.func.attr)) + if isinstance(node.func, ast.Name): + return self.get_llvm_type_str(node.func) self._symtab.diagnostics.warn('', 0, "无法解析 Call 类型,回退到 i32") return 'i32' diff --git a/lib/core/SymbolExtractor.py b/lib/core/SymbolExtractor.py index f63b41f..229f6b9 100644 --- a/lib/core/SymbolExtractor.py +++ b/lib/core/SymbolExtractor.py @@ -10,9 +10,9 @@ from lib.core.SymbolData import ( FuncSymbolData, DefineSymbolData, AnonymousTypeData ) from lib.core.Handles.HandlesBase import CTypeInfo -from lib.core.SymbolUtils import AnnotationContainsTType, CheckAnnotationHasCInline, IsTModule, AnnotationContainsName +from lib.core.SymbolUtils import AnnotationContainsMarker, CheckAnnotationHasCInline, AnnotationContainsName from lib.core.SymbolUtils import EnumClassIntWidth, _ENUM_DEFAULT_INT_WIDTH -from lib.includes import t +from lib.core import TypeSystem class ASTSymbolExtractor: @@ -62,7 +62,7 @@ class ASTSymbolExtractor: member_type: CTypeInfo | None = CTypeInfo.FromNode(item.annotation, self._symtab) if member_type is None: member_type = CTypeInfo() - member_type.BaseType = t.CInt() + member_type.BaseType = TypeSystem.CInt() is_ptr: bool = member_type.IsPtr if isinstance(item.annotation, ast.BinOp): if AnnotationContainsName(item.annotation, 'CPtr'): @@ -71,24 +71,24 @@ class ASTSymbolExtractor: elif isinstance(item, ast.ClassDef): is_anonymous: bool = any( - any(AnnotationContainsTType(base, 'Anonymous') for base in item.bases) + any(AnnotationContainsMarker(base, 'Anonymous') for base in item.bases) ) if item.bases else False if is_anonymous: is_union: bool = any( - any(AnnotationContainsTType(base, 'CUnion') for base in item.bases) + any(AnnotationContainsMarker(base, 'CUnion') for base in item.bases) ) - # 也检查装饰器形式 @t.CUnion + # 也检查装饰器形式 @CUnion if not is_union and hasattr(item, 'decorator_list') and item.decorator_list: for deco in item.decorator_list: - if isinstance(deco, ast.Attribute) and hasattr(deco.value, 'id') and IsTModule(deco.value.id, self._symtab) and deco.attr == 'CUnion': + if isinstance(deco, ast.Attribute) and hasattr(deco.value, 'id') and deco.attr == 'CUnion': is_union = True break elif isinstance(deco, ast.Name): - cls2: type | None = getattr(t, deco.id, None) - if cls2 is None and hasattr(self._symtab, '_t_type_symbols'): - cls2 = self._symtab._t_type_symbols.get(deco.id) - if cls2 is not None and isinstance(cls2, type) and issubclass(cls2, t.CUnion): + cls2: type | None = getattr(TypeSystem, deco.id, None) + if cls2 is None and hasattr(self._symtab, '_builtin_type_symbols'): + cls2 = self._symtab._builtin_type_symbols.get(deco.id) + if cls2 is not None and isinstance(cls2, type) and issubclass(cls2, TypeSystem.CUnion): is_union = True break @@ -129,8 +129,7 @@ class ASTSymbolExtractor: if hasattr(node, 'decorator_list') and node.decorator_list: for decorator in node.decorator_list: if isinstance(decorator, ast.Attribute): - if (hasattr(decorator.value, 'id') and - IsTModule(decorator.value.id, self._symtab)): + if (hasattr(decorator.value, 'id') ): if decorator.attr == 'Object': is_cpython_object = True elif decorator.attr == 'CUnion': @@ -143,44 +142,42 @@ class ASTSymbolExtractor: type_kind = 'struct' elif isinstance(decorator, ast.Name): # from t import CStruct / CUnion / CEnum / REnum - cls: type | None = getattr(t, decorator.id, None) - if cls is None and hasattr(self._symtab, '_t_type_symbols'): - cls = self._symtab._t_type_symbols.get(decorator.id) - if cls is not None and isinstance(cls, type) and issubclass(cls, t.CType): - if issubclass(cls, t.CUnion): + cls: type | None = getattr(TypeSystem, decorator.id, None) + if cls is None and hasattr(self._symtab, '_builtin_type_symbols'): + cls = self._symtab._builtin_type_symbols.get(decorator.id) + if cls is not None and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): + if issubclass(cls, TypeSystem.CUnion): type_kind = 'union' - elif issubclass(cls, t.REnum): + elif issubclass(cls, TypeSystem.REnum): type_kind = 'renum' - elif issubclass(cls, t.CEnum): + elif issubclass(cls, TypeSystem.CEnum): type_kind = 'enum' - elif issubclass(cls, t.CStruct): + elif issubclass(cls, TypeSystem.CStruct): type_kind = 'struct' elif decorator.id == 'Object': is_cpython_object = True elif isinstance(decorator, ast.Call): - if isinstance(decorator.func, ast.Attribute): - if hasattr(decorator.func.value, 'id') and decorator.func.value.id == 'c' and decorator.func.attr == 'Attribute': - for arg in decorator.args: - if isinstance(arg, ast.Attribute): - if isinstance(arg.value, ast.Attribute): - if hasattr(arg.value.value, 'id') and IsTModule(arg.value.value.id, self._symtab) and arg.value.attr == 'attr' and arg.attr == 'packed': - is_packed = True + if isinstance(decorator.func, ast.Name) and decorator.func.id == 'Attribute': + for arg in decorator.args: + if (isinstance(arg, ast.Attribute) and arg.attr == 'packed' + and isinstance(arg.value, ast.Name) and arg.value.id == 'attr'): + is_packed = True # 检查基类 for base in node.bases: - if AnnotationContainsTType(base, 'CUnion'): + if AnnotationContainsMarker(base, 'CUnion'): type_kind = 'union' break - elif AnnotationContainsTType(base, 'CEnum'): + elif AnnotationContainsMarker(base, 'CEnum'): type_kind = 'enum' break - elif AnnotationContainsTType(base, 'REnum'): + elif AnnotationContainsMarker(base, 'REnum'): type_kind = 'renum' break - elif AnnotationContainsTType(base, 'CStruct'): + elif AnnotationContainsMarker(base, 'CStruct'): type_kind = 'struct' break - elif AnnotationContainsTType(base, 'Object'): + elif AnnotationContainsMarker(base, 'Object'): is_cpython_object = True type_kind = 'struct' break @@ -275,9 +272,9 @@ class ASTSymbolExtractor: def _extract_ann_assign(self, node: ast.AnnAssign, result: ModuleSymbols) -> None: """从 AnnAssign 节点提取 typedef 或 define 数据""" var_name: str = node.target.id - has_cdefine: bool = AnnotationContainsTType(node.annotation, 'CDefine') if node.annotation else False - has_postdef: bool = AnnotationContainsTType(node.annotation, 'Postdefinition') if node.annotation else False - has_ctypedef: bool = AnnotationContainsTType(node.annotation, 'CTypedef') if node.annotation else False + has_cdefine: bool = AnnotationContainsMarker(node.annotation, 'CDefine') if node.annotation else False + has_postdef: bool = AnnotationContainsMarker(node.annotation, 'Postdefinition') if node.annotation else False + has_ctypedef: bool = AnnotationContainsMarker(node.annotation, 'CTypedef') if node.annotation else False if has_cdefine: result.defines.append(DefineSymbolData( diff --git a/lib/core/SymbolNode.py b/lib/core/SymbolNode.py index f1aa0ef..14f714e 100644 --- a/lib/core/SymbolNode.py +++ b/lib/core/SymbolNode.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any, Dict, Optional from lib.core.Handles.HandlesBase import CTypeInfo -from lib.includes import t +from lib.core import TypeSystem class SymbolNode: @@ -168,11 +168,11 @@ class SymbolNode: if resolved and resolved.BaseType: CTypeMember = resolved else: - CTypeMember.BaseType = t.CInt() + CTypeMember.BaseType = TypeSystem.CInt() except Exception: - CTypeMember.BaseType = t.CInt() + CTypeMember.BaseType = TypeSystem.CInt() else: - CTypeMember.BaseType = t.CInt() + CTypeMember.BaseType = TypeSystem.CInt() if IsPtr and not CTypeMember.IsPtr: CTypeMember.PtrCount = max(CTypeMember.PtrCount, 1) node.attributes.Members[MemberName] = CTypeMember @@ -206,7 +206,7 @@ class SymbolNode: @classmethod def CreateAnonymous(cls, name: str, IsUnion: bool, members: dict, lineno: int = 0, file: str = '') -> SymbolNode: """创建匿名类型节点(工厂函数)""" - NodeType: type = t.CUnion if IsUnion else t.CStruct + NodeType: type = TypeSystem.CUnion if IsUnion else TypeSystem.CStruct node: SymbolNode = cls(name=name, NodeType=NodeType, lineno=lineno, file=file) node.attributes = CTypeInfo() node.attributes.Name = name diff --git a/lib/core/SymbolTable.py b/lib/core/SymbolTable.py index c2135f9..9a7149c 100644 --- a/lib/core/SymbolTable.py +++ b/lib/core/SymbolTable.py @@ -7,7 +7,7 @@ import vast as ast import traceback from lib.core.Handles.HandlesBase import CTypeInfo -from lib.includes import t +from lib.core import TypeSystem from lib.core.VLogger import get_logger as _vlog from lib.core.DiagnosticCollector import DiagnosticCollector from lib.core.LLVMTypeMapper import LLVMTypeMapper, TypeNameUnresolvedError @@ -27,7 +27,7 @@ class SymbolTable: self.translator: Translator = translator self._symbols: dict[str, CTypeInfo] = {} self._namespaces: dict[str, dict[str, CTypeInfo]] = {} # 模块名 -> 符号字典 - self._t_type_symbols: dict[str, type] = {} # 别名 -> t.CType 子类 (from t import CEnum as en) + self._builtin_type_symbols: dict[str, type] = {} # 别名 -> CType 子类 (from t import CEnum as en) self.diagnostics: DiagnosticCollector = DiagnosticCollector() self._type_mapper: LLVMTypeMapper = LLVMTypeMapper(self) self.import_aliases: dict[str, str] = {} # 别名 -> 模块路径 @@ -50,7 +50,7 @@ class SymbolTable: def clear(self) -> None: self._symbols.clear() self._namespaces.clear() - self._t_type_symbols.clear() + self._builtin_type_symbols.clear() self.import_aliases.clear() def get(self, name: str, default: CTypeInfo | None = None) -> CTypeInfo | None: @@ -110,7 +110,7 @@ class SymbolTable: 解析顺序: 1. 直接匹配 _symbols 2. 如果包含 '.',解析第一个段为别名后查找剩余路径 - 3. 查 _t_type_symbols(t/c 类型别名,返回模拟 CTypeInfo) + 3. 查 _builtin_type_symbols(t/c 类型别名,返回模拟 CTypeInfo) """ if name in self._symbols: return self._symbols[name] @@ -136,18 +136,18 @@ class SymbolTable: return None def _lookup_t_type(self, name: str) -> CTypeInfo | None: - """在 _t_type_symbols 中查找 t/c 类型别名,返回模拟 CTypeInfo""" - cls: type | None = self._t_type_symbols.get(name) + """在 _builtin_type_symbols 中查找 t/c 类型别名,返回模拟 CTypeInfo""" + cls: type | None = self._builtin_type_symbols.get(name) if cls is None: return None info: CTypeInfo = CTypeInfo() info.Name = name info.BaseType = cls() - if issubclass(cls, (t.CEnum, t.REnum)): + if issubclass(cls, (TypeSystem.CEnum, TypeSystem.REnum)): info.IsEnum = True - elif issubclass(cls, t.CUnion): + elif issubclass(cls, TypeSystem.CUnion): info.IsUnion = True - elif issubclass(cls, t.CStruct): + elif issubclass(cls, TypeSystem.CStruct): info.IsStruct = True return info @@ -227,20 +227,20 @@ class SymbolTable: } if self.import_aliases: result['__import_aliases__'] = dict(self.import_aliases) - if self._t_type_symbols: - result['__t_type_symbols__'] = { - name: cls.__name__ for name, cls in self._t_type_symbols.items() + if self._builtin_type_symbols: + result['__builtin_type_symbols__'] = { + name: cls.__name__ for name, cls in self._builtin_type_symbols.items() } return result @staticmethod - def _SerializeBaseType(base_type: t.CType | tuple | list | str | None) -> dict | str: + def _SerializeBaseType(base_type: TypeSystem.CType | tuple | list | str | None) -> dict | str: """将 BaseType 序列化为可重建的格式""" - if isinstance(base_type, t.CType): + if isinstance(base_type, TypeSystem.CType): return {'class': type(base_type).__name__} if isinstance(base_type, (tuple, list)): - return {'classes': [type(b).__name__ for b in base_type if isinstance(b, t.CType)]} + return {'classes': [type(b).__name__ for b in base_type if isinstance(b, TypeSystem.CType)]} return str(base_type) @staticmethod @@ -248,20 +248,20 @@ class SymbolTable: """从序列化格式恢复 BaseType""" if isinstance(data, dict): if 'class' in data: - cls: type | None = getattr(t, data['class'], None) - if cls and isinstance(cls, type) and issubclass(cls, t.CType): + cls: type | None = getattr(TypeSystem, data['class'], None) + if cls and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): return cls() elif 'classes' in data: - types: list[t.CType] = [] + types: list[TypeSystem.CType] = [] for cname in data['classes']: - cls: type | None = getattr(t, cname, None) - if cls and isinstance(cls, type) and issubclass(cls, t.CType): + cls: type | None = getattr(TypeSystem, cname, None) + if cls and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): types.append(cls()) if types: return tuple(types) elif isinstance(data, str): - cls: type | None = getattr(t, data, None) - if cls and isinstance(cls, type) and issubclass(cls, t.CType): + cls: type | None = getattr(TypeSystem, data, None) + if cls and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): return cls() return None @@ -270,9 +270,9 @@ class SymbolTable: self._symbols.clear() self._namespaces.clear() self.import_aliases.clear() - self._t_type_symbols.clear() + self._builtin_type_symbols.clear() - _SPECIAL_KEYS: frozenset[str] = frozenset({'__namespaces__', '__import_aliases__', '__t_type_symbols__'}) + _SPECIAL_KEYS: frozenset[str] = frozenset({'__namespaces__', '__import_aliases__', '__builtin_type_symbols__'}) for name, attrs in symbols.items(): if name in _SPECIAL_KEYS: @@ -296,12 +296,12 @@ class SymbolTable: self.import_aliases.update(aliases_data) # 恢复 t 类型别名 - t_type_data: dict[str, str] | None = symbols.get('__t_type_symbols__') + t_type_data: dict[str, str] | None = symbols.get('__builtin_type_symbols__') if t_type_data: for name, cls_name in t_type_data.items(): - cls: type | None = getattr(t, cls_name, None) - if cls and isinstance(cls, type) and issubclass(cls, t.CType): - self._t_type_symbols[name] = cls + cls: type | None = getattr(TypeSystem, cls_name, None) + if cls and isinstance(cls, type) and issubclass(cls, TypeSystem.CType): + self._builtin_type_symbols[name] = cls def _CTypeInfoFromDict(self, name: str, attrs: dict[str, Any]) -> CTypeInfo: """从旧 dict 格式创建 CTypeInfo(兼容旧代码)""" @@ -378,7 +378,7 @@ class SymbolTable: # 两阶段加载(顺序无关):声明阶段 / 签名阶段 # # 为什么要拆:签名解析(Pass 2 的函数部分)会通过符号表查找**其它模块**的 - # 类型名(裸名 typedef,如 posix 的 `INT | t.State`;跨模块类,如 + # 类型名(裸名 typedef,如 posix 的 `INT | State`;跨模块类,如 # `rawptr[Constant]`)。单模块逐个「提取→解析→插入」时,这些名字要求依赖模块 # **恰好先被加载**(Phase2Translator 按 os.listdir 字典序加载 ⇒ posix 排在 # stdint 之前,`INT` 找不到)。旧口径把它静默降级成 i32,所以顺序依赖不可见; @@ -578,7 +578,7 @@ class SymbolTable: info.IsVariadic = IsVariadic info.IsInline = IsInline if IsInline: - info.Storage = t.CInline() + info.Storage = TypeSystem.CInline() info.Lineno = lineno info.file = FilePath self._symbols[FullName] = info diff --git a/lib/core/SymbolTypeResolver.py b/lib/core/SymbolTypeResolver.py index 519cf62..38c8c56 100644 --- a/lib/core/SymbolTypeResolver.py +++ b/lib/core/SymbolTypeResolver.py @@ -10,8 +10,7 @@ from lib.core.SymbolData import ( ) from lib.core.Handles.HandlesBase import CTypeInfo, CTypeHelper, BuiltinTypeMap from lib.core.LLVMTypeMapper import LLVMTypeMapper, TypeNameUnresolvedError -from lib.core.SymbolUtils import IsTModule -from lib.includes import t +from lib.core import TypeSystem class TypeResolver: @@ -109,12 +108,12 @@ class TypeResolver: original_type_kind: str = 'struct' if original_class in self._symtab: orig_type_info: CTypeInfo = self._symtab[original_class] - if orig_type_info.type_cls in (t.CStruct, t.CEnum, t.CUnion): - if orig_type_info.type_cls is t.CStruct: + if orig_type_info.type_cls in (TypeSystem.CStruct, TypeSystem.CEnum, TypeSystem.CUnion): + if orig_type_info.type_cls is TypeSystem.CStruct: original_type_kind = 'struct' - elif orig_type_info.type_cls is t.CEnum: + elif orig_type_info.type_cls is TypeSystem.CEnum: original_type_kind = 'enum' - elif orig_type_info.type_cls is t.CUnion: + elif orig_type_info.type_cls is TypeSystem.CUnion: original_type_kind = 'union' td.original_type_kind = original_type_kind td.original_class = original_class @@ -149,7 +148,7 @@ class TypeResolver: def _resolve_typedef_from_value(self, td: TypedefSymbolData): """从值表达式解析 typedef 类型 - BinOp(如 UINT | t.CPtr)优先于 _find_base_type 处理, + BinOp(如 UINT | CPtr)优先于 _find_base_type 处理, 因为 _find_base_type 是静态方法无法解析 Name 引用(如 UINT)。 """ if not td.value: @@ -182,13 +181,13 @@ class TypeResolver: value_base_type: str | None = self._find_base_type(td.value) _PTR_MODIFIERS: frozenset[str] = frozenset({'CPtr', 'CArrayPtr', 'CConst', 'CVolatile', 'CInline', 'CStatic', 'CExtern'}) - # 裸 t.CPtr(无 `|` 联合、无 `[T]` 下标):_find_base_type 把 node.attr == 'CPtr' + # 裸 CPtr(无 `|` 联合、无 `[T]` 下标):_find_base_type 把 node.attr == 'CPtr' # 归一化为指针标记 'ptr'(拼写与 _PTR_MODIFIERS 的 'CPtr' 不一致 ⇒ 下方守卫命不中), # 若让 'ptr' 落进 original_class,经 _InsertTypedefSymbol 存入 symtab.OriginalType 后 # 会被 CTypeInfo.FromTypeName 当成 CStruct('ptr'),最终 _get_or_create_struct # 建出 %"<模块sha>.ptr" 不透明结构体(VLogger._console_handle: win32base.HANDLE # 报 "cannot store i8* to %"...ptr"*" 的根因)。按指针语义展开为 'void *', - # 与改前 `t.CPtr` 联合分支等价(_InsertTypedefSymbol 同样把 + # 与改前 `CPtr` 联合分支等价(_InsertTypedefSymbol 同样把 # 'CVoid *' 归一化为 'void *')。 if value_base_type == 'ptr': td.original_type_kind = 'typedef' @@ -223,12 +222,12 @@ class TypeResolver: # 最后兜底:builtins.vp 的短别名(int8/uint64/uchar/ushort/sizet…) # 与内建速记(int/char/float/bool/str…)。 - # `_find_base_type` 只认 `t.X`(ast.Attribute)形态,裸名根本走不到上面 - # 的 GetCName 分支 ⇒ `X: t.CTypedef = int64` 这类声明此前整条解析失败, + # `_find_base_type` 只认 `X`(ast.Attribute)形态,裸名根本走不到上面 + # 的 GetCName 分支 ⇒ `X: CTypedef = int64` 这类声明此前整条解析失败, # X 不登记进符号表,用到处报「裸名 X 无法解析为类型」 # (现场:includes/posix.vp 的 off_t、stdint.vp 的 INT)。 # 此分支与注解位置 LLVMTypeMapper._resolve_name 的来源一致,产物形态也 - # 与 `t.CInt64T` 分支逐字相同(original_class 存 t.C 类名)。 + # 与 `CInt64T` 分支逐字相同(original_class 存 t.C 类名)。 builtin_info: CTypeInfo | None = self._type_mapper._lookup_builtins_typedef(ref_name) if builtin_info is None: _entry: tuple[type, int] | None = BuiltinTypeMap.Get(ref_name) @@ -239,7 +238,7 @@ class TypeResolver: if builtin_info is not None and builtin_info.BaseType: _bt: object = builtin_info.BaseType # BaseType 可能是 t.C 类名(str)、CType 子类,或 CType **实例** - # (_lookup_builtins_typedef 走的是 t.CInt64T() 实例); + # (_lookup_builtins_typedef 走的是 CInt64T() 实例); # CTypeHelper.GetCName 只认前两种 ⇒ 实例取 type(x).__name__。 if isinstance(_bt, str): _cname: str = _bt @@ -258,7 +257,7 @@ class TypeResolver: def _resolve_type_expr(self, node: ast.AST) -> str: """解析类型表达式为 C 类型名字符串,优先查本模块已解析的 typedef - 解决同模块 typedef 间引用(如 UINTPTR = UINT | t.CPtr 中的 UINT) + 解决同模块 typedef 间引用(如 UINTPTR = UINT | CPtr 中的 UINT) 在 TypeResolver 阶段尚未插入 symtab 的问题。 """ if isinstance(node, ast.Name): @@ -342,12 +341,12 @@ class TypeResolver: def _find_base_type(node: ast.AST | None) -> str | None: """从注解 AST 节点中查找基础类型名称""" if isinstance(node, ast.Attribute): - if hasattr(node.value, 'id') and IsTModule(node.value.id): + if hasattr(node.value, 'id') : if node.attr == 'CPtr': return 'ptr' return node.attr elif isinstance(node, ast.Subscript): - if isinstance(node.value, ast.Attribute) and isinstance(node.value.value, ast.Name) and IsTModule(node.value.value.id) and node.value.attr == 'Callable': + if isinstance(node.value, ast.Attribute) and isinstance(node.value.value, ast.Name) and node.value.attr == 'Callable': return 'Callable' elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): left_result: str | None = TypeResolver._find_base_type(node.left) @@ -378,7 +377,7 @@ class TypeResolver: """从注解 AST 节点中查找 Postdefinition 参数""" if isinstance(node, ast.Call): if isinstance(node.func, ast.Attribute): - if hasattr(node.func.value, 'id') and IsTModule(node.func.value.id) and node.func.attr == 'Postdefinition': + if hasattr(node.func.value, 'id') and node.func.attr == 'Postdefinition': if node.args and isinstance(node.args[0], ast.Name): return node.args[0].id elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): diff --git a/lib/core/SymbolUtils.py b/lib/core/SymbolUtils.py index 2d2d37b..43a73a8 100644 --- a/lib/core/SymbolUtils.py +++ b/lib/core/SymbolUtils.py @@ -4,10 +4,8 @@ import io import tokenize import vast as ast import re -from lib.includes import t -from lib.includes.t import CTypeRegistry - -_T_MODULE_NAMES: frozenset[str] = frozenset({'t', t.__name__}) +from lib.core import TypeSystem +from lib.core.TypeSystem import CTypeRegistry # Viper 软关键字 fn/fun/func/function 是 def 的别名(行首 + 空白 + 标识符才算函数定义, # 变量名/调用/注解中的 fn 不受影响)。展开为 def 后行号不变,供 ast.parse 使用。 @@ -16,14 +14,14 @@ _SOFT_KEYWORD_RE: re.Pattern[str] = re.compile( ) # enum 语句(Viper 语法糖):`enum Name:` + 成员行,与 -# `class Name(t.CEnum):` **完全等价**(同一实现路径——展开后再解析, -# 下游 EnumTable/符号表注册只看 ClassDef + t.CEnum 基类,不存在第二套枚举实现)。 -# 头行 enum Name: → class Name(t.CEnum): -# 裸成员 Name → Name: t.State(默认 i32;必须落为 AnnAssign, +# `class Name(CEnum):` **完全等价**(同一实现路径——展开后再解析, +# 下游 EnumTable/符号表注册只看 ClassDef + CEnum 基类,不存在第二套枚举实现)。 +# 头行 enum Name: → class Name(CEnum): +# 裸成员 Name → Name: State(默认 i32;必须落为 AnnAssign, # 否则 Enum/REnum 成员收集按 Assign/AnnAssign 过滤会漏掉裸名语句) # 带注解 Name: T → 原样保留(自定义具体类型) # 带值 Name = 0 → 原样保留(Assign 形态,两侧枚举收集均支持) -# 多名行 A, B, C → A: t.State; B: t.State; C: t.State(同行分号分隔,见下; +# 多名行 A, B, C → A: State; B: State; C: State(同行分号分隔,见下; # 可带尾随逗号 A, B,,与 VPC 的 AST 口径一致) _ENUM_HEAD_RE: re.Pattern[str] = re.compile( r'^(\s*)enum(\s+)([A-Za-z_]\w*)(\s*):([ \t]*(?:#.*)?)$' @@ -35,13 +33,13 @@ _ENUM_MEMBER_BARE_RE: re.Pattern[str] = re.compile( # 只匹配"纯标识符列表 + 可选尾随逗号 + 可选注释",故 `A, B = 1`(Assign)、 # `A, B: int`(带注解)与 `f(a, b)`(调用)都不命中,原样保留(由注册处的 # EnumBodyMemberNames 兜底判据 fail-fast,不再静默丢成员)。 -# 尾随逗号必须支持:VPC 侧走 AST(`class X(t.CEnum): A, B,` 与 `A, B` 在 AST 上 +# 尾随逗号必须支持:VPC 侧走 AST(`class X(CEnum): A, B,` 与 `A, B` 在 AST 上 # 完全同形,无法区分),TPC 若在此拒绝会造成"同源两种编译器两种结果"。group(3) # 只收注释正文(不含前导空白/逗号),展开时另行补一个空格。 _ENUM_MEMBER_LIST_RE: re.Pattern[str] = re.compile( r'^(\s*)([A-Za-z_]\w*(?:[ \t]*,[ \t]*[A-Za-z_]\w*)+)[ \t]*,?[ \t]*((?:#.*)?)$' ) -# 裸名语句保留集:这些行是语句而非枚举成员,展开时不得追加 `: t.State` +# 裸名语句保留集:这些行是语句而非枚举成员,展开时不得追加 `: State` _ENUM_MEMBER_SKIP: frozenset[str] = frozenset({ 'pass', 'return', 'break', 'continue', 'global', 'nonlocal', 'raise', 'yield', 'import', 'from', 'del', 'assert', 'if', 'while', 'for', 'with', @@ -62,15 +60,15 @@ _RE_ATTR_CALL_IDENT: re.Pattern[str] = re.compile(r'^[A-Za-z_][A-Za-z0-9_]*\s*\( def _ExpandEnumBlocks(Code: str) -> str: - """把 `enum Name:` 块展开为等价的 `class Name(t.CEnum):` 块(行号不变)。 + """把 `enum Name:` 块展开为等价的 `class Name(CEnum):` 块(行号不变)。 只在"行首缩进 + enum + 空白 + 标识符 + 冒号(行尾)"的枚举头形态触发: `enum = 5` / `import enum` / `x.enum` / 注解 `x: enum` 均不匹配。 成员行只对块内"更深缩进"的行做展开,块内空行与注释行原样保留; 缩进回到枚举头同级(或更浅)即块结束。全程不增删换行,行号映射保持有效。 - 成员行两种形态:单名(`Name`)追加 `: t.State`;逗号分组多名(`Add, Sub`) - 在同一行内展开为分号分隔的多个 `Name: t.State`(简单语句,`vast` 与 Python + 成员行两种形态:单名(`Name`)追加 `: State`;逗号分组多名(`Add, Sub`) + 在同一行内展开为分号分隔的多个 `Name: State`(简单语句,`vast` 与 Python 均按多个 AnnAssign 解析)。未展开的一行多名语句会被当作元组表达式,下游 枚举成员收集(仅认 Assign/AnnAssign)会静默漏掉这些成员。 """ @@ -95,7 +93,7 @@ def _ExpandEnumBlocks(Code: str) -> str: i += 1 continue indent: str = head.group(1) - out.append(f'{indent}class {head.group(3)}(t.CEnum):{head.group(5)}{term}') + out.append(f'{indent}class {head.group(3)}(CEnum):{head.group(5)}{term}') i += 1 while i < n: raw2: str = lines[i] @@ -113,10 +111,10 @@ def _ExpandEnumBlocks(Code: str) -> str: break # 缩进回到枚举头同级:块结束(该行留给外层循环) member = _ENUM_MEMBER_BARE_RE.match(body2) if member is not None and member.group(2) not in _ENUM_MEMBER_SKIP: - out.append(f'{member.group(1)}{member.group(2)}: t.State{member.group(3)}{term2}') + out.append(f'{member.group(1)}{member.group(2)}: State{member.group(3)}{term2}') else: # 逗号分组成员行:同一行展开为"分号分隔的多个 AnnAssign"。 - # `Name: t.State` 是简单语句,分号分隔在 Python 与 vast 中均合法 + # `Name: State` 是简单语句,分号分隔在 Python 与 vast 中均合法 # ⇒ 与单名成员行产出同一批 AnnAssign(枚举成员/宽度/编号全部一致), # 且不增删换行,行号映射保持有效。group(3) 是注释正文(可为空), # 需要时补一个空格再接回(尾随逗号已在正则里吃掉,不参与拼接)。 @@ -124,7 +122,7 @@ def _ExpandEnumBlocks(Code: str) -> str: names: list[str] = ([nm.strip() for nm in member_list.group(2).split(',')] if member_list is not None else []) if names and all(nm not in _ENUM_MEMBER_SKIP for nm in names): - joined: str = '; '.join(f'{nm}: t.State' for nm in names) + joined: str = '; '.join(f'{nm}: State' for nm in names) tail: str = member_list.group(3) comment: str = f' {tail}' if tail else '' out.append(f'{member_list.group(1)}{joined}{comment}{term2}') @@ -135,7 +133,7 @@ def _ExpandEnumBlocks(Code: str) -> str: # Viper soft keyword `union` (statement-level reserved word): `union X:` is exactly -# `class X(t.CUnion):` (same desugar target as VPC includes/ast/parser.vp:_parse_uniondef). +# `class X(CUnion):` (same desugar target as VPC includes/ast/parser.vp:_parse_uniondef). # Unlike enum, union members are ordinary annotated fields, so no member rewriting. # `union` is not used as an identifier anywhere in .vp sources. _UNION_HEAD_RE: re.Pattern[str] = re.compile( @@ -145,7 +143,7 @@ _UNION_PREFIX_RE: re.Pattern[str] = re.compile(r'^(\s*)union\b') def _ExpandUnionBlocks(Code: str) -> str: - """Expand `union Name:` into `class Name(t.CUnion):` (same-line, line numbers kept). + """Expand `union Name:` into `class Name(CUnion):` (same-line, line numbers kept). Mirrors VPC _parse_uniondef: the body is ordinary AnnAssign fields, so only the head line is rewritten. A line starting with `union` that is not the exact @@ -162,12 +160,12 @@ def _ExpandUnionBlocks(Code: str) -> str: term: str = raw[k:] head = _UNION_HEAD_RE.match(body) if head is not None: - out.append(f'{head.group(1)}class {head.group(3)}(t.CUnion):{head.group(5)}{term}') + out.append(f'{head.group(1)}class {head.group(3)}(CUnion):{head.group(5)}{term}') continue if _UNION_PREFIX_RE.match(body) is not None: raise SyntaxError( f"union 语法错误(行 {Lineno},原文: {body.strip()!r}):应为 `union 名字:`" - f"(等价于 `class 名字(t.CUnion):`)。union 是语句级保留字,成员必须写成 " + f"(等价于 `class 名字(CUnion):`)。union 是语句级保留字,成员必须写成 " f"`名字: 类型`;非法形态一律终止编译(非静默)。" ) out.append(raw) @@ -175,7 +173,7 @@ def _ExpandUnionBlocks(Code: str) -> str: # Viper soft keyword `renum` (statement-level reserved word): `renum X:` is exactly -# `class X(t.REnum):` (same desugar target as VPC includes/ast/parser.vp:_parse_renumdef). +# `class X(REnum):` (same desugar target as VPC includes/ast/parser.vp:_parse_renumdef). # REnum members are ordinary class-body statements (nested `class V:` variants and # bare assignments like `None_ = 0`), so only the head line is rewritten. # `renum` is not used as an identifier anywhere in .vp sources. @@ -186,7 +184,7 @@ _RENUM_PREFIX_RE: re.Pattern[str] = re.compile(r'^(\s*)renum\b') def _ExpandRenumBlocks(Code: str) -> str: - """Expand `renum Name:` into `class Name(t.REnum):` (same-line, line numbers kept). + """Expand `renum Name:` into `class Name(REnum):` (same-line, line numbers kept). Mirrors VPC _parse_renumdef: the body is an ordinary class body (variant classes written as nested `class V:` plus payload-less assignments such as `None_ = 0`), @@ -204,12 +202,12 @@ def _ExpandRenumBlocks(Code: str) -> str: term: str = raw[k:] head = _RENUM_HEAD_RE.match(body) if head is not None: - out.append(f'{head.group(1)}class {head.group(3)}(t.REnum):{head.group(5)}{term}') + out.append(f'{head.group(1)}class {head.group(3)}(REnum):{head.group(5)}{term}') continue if _RENUM_PREFIX_RE.match(body) is not None: raise SyntaxError( f"renum 语法错误(行 {Lineno},原文: {body.strip()!r}):应为 `renum 名字:`" - f"(等价于 `class 名字(t.REnum):`)。renum 是语句级保留字,成员写成嵌套 " + f"(等价于 `class 名字(REnum):`)。renum 是语句级保留字,成员写成嵌套 " f"`class 变体:` 或无载荷赋值(如 `None_ = 0`);非法形态一律终止编译(非静默)。" ) out.append(raw) @@ -217,27 +215,27 @@ def _ExpandRenumBlocks(Code: str) -> str: # --------------------------------------------------------------------------- -# define 常量声明(Viper 语法糖)——与 `NAME: t.CDefine = 值` **完全等价** +# define 常量声明(Viper 语法糖)——与 `NAME: CDefine = 值` **完全等价** # --------------------------------------------------------------------------- -# 带类型 define NAME: T = <表达式> → NAME: T | t.CDefine = <表达式> -# 不带类型 define NAME = <表达式> → NAME: t.CDefine = <表达式> +# 带类型 define NAME: T = <表达式> → NAME: T | CDefine = <表达式> +# 不带类型 define NAME = <表达式> → NAME: CDefine = <表达式> # -# 语义:编译期常量声明,落到**既有的** t.CDefine 注册路径(TPC: +# 语义:编译期常量声明,落到**既有的** CDefine 注册路径(TPC: # LlvmGenerator._register_cdefine_constant / HandlesAnnAssign 的 IsDefine 分支; # 跨模块:SymbolExtractor → SymbolTable → .vpi/.pyi → HandlesImports), -# 不新增第二套常量实现。可见性与 `t.CDefine` 常量完全一致: +# 不新增第二套常量实现。可见性与 `CDefine` 常量完全一致: # 模块级 / 类体内 / 函数内 三种位置均可(各自走既有注册点)。 # -# 为什么带类型写成 `T | t.CDefine`(**类型在前**)而不是既有手写惯用法的 -# `t.CDefine | T`:HandlesTypeMerge._MergeCTypeInfoInto 的 BaseType 采用 +# 为什么带类型写成 `T | CDefine`(**类型在前**)而不是既有手写惯用法的 +# `CDefine | T`:HandlesTypeMerge._MergeCTypeInfoInto 的 BaseType 采用 # "首个非 void 基类型胜出"(`if Target.BaseType is None: Target.BaseType = Source.BaseType`), -# 而 _CollectAllOperandTypes 按**书写顺序**左→右展开 ⇒ `t.CDefine | T` 的 -# BaseType 会停在 t.CDefine,显式类型 T 被**丢弃**(既有手写形态的既有事实, +# 而 _CollectAllOperandTypes 按**书写顺序**左→右展开 ⇒ `CDefine | T` 的 +# BaseType 会停在 CDefine,显式类型 T 被**丢弃**(既有手写形态的既有事实, # 见 Test/DefineTest/App/main.vp:30-32);把 T 写在前面才能让 BaseType = T, # 从而让"值必须能放进 T"这条判据有据可依(同时也是显式类型的真实含义)。 # # 只在"行首缩进 + define + 标识符 + (`=` 或 `: … =`)"形态触发: -# - `define NAME(...)`(既有宏函数软关键字,返回注解自动追加 t.CDefine, +# - `define NAME(...)`(既有宏函数软关键字,返回注解自动追加 CDefine, # 见 lib/vast/Parser.py:_ParseDefineDef)后跟 `(`,两个正则都不命中 ⇒ 原样保留; # - 把 define 当标识符的写法(`define = 5` / `define(x)`)同样不命中; # - 同行替换、不增删换行 ⇒ 行号映射保持有效(与 fn/enum 同约定)。 @@ -250,7 +248,7 @@ _DEFINE_CONST_PLAIN_RE: re.Pattern[str] = re.compile( def _ExpandDefineConsts(Code: str) -> str: - """把 `define NAME[: T] = 值` 展开为等价的 `NAME: [T |] t.CDefine = 值`(行号不变)。 + """把 `define NAME[: T] = 值` 展开为等价的 `NAME: [T |] CDefine = 值`(行号不变)。 逐行处理:行终止符(LF/CRLF/CR)单独拆出后原样回写(与 _ExpandEnumBlocks 同约定,避免行尾 '\\r' 让 `$` 锚定的正则失配而**静默不展开**)。 @@ -270,30 +268,30 @@ def _ExpandDefineConsts(Code: str) -> str: typed = _DEFINE_CONST_TYPED_RE.match(body) if typed is not None: out.append(f'{typed.group(1)}{typed.group(2)}: ' - f'{typed.group(3).strip()} | t.CDefine ={typed.group(4)}{term}') + f'{typed.group(3).strip()} | CDefine ={typed.group(4)}{term}') continue plain = _DEFINE_CONST_PLAIN_RE.match(body) if plain is not None: - out.append(f'{plain.group(1)}{plain.group(2)}: t.CDefine ={plain.group(3)}{term}') + out.append(f'{plain.group(1)}{plain.group(2)}: CDefine ={plain.group(3)}{term}') continue out.append(raw) return ''.join(out) # --------------------------------------------------------------------------- -# typedef 类型别名声明(Viper 语法糖)——与 `T1: t.CTypedef = T2` **完全等价** +# typedef 类型别名声明(Viper 语法糖)——与 `T1: CTypedef = T2` **完全等价** # --------------------------------------------------------------------------- -# typedef T1 = T2 → T1: t.CTypedef = T2 +# typedef T1 = T2 → T1: CTypedef = T2 # -# 语义:与手写 `T1: t.CTypedef = T2` 落到**同一条** typedef 注册/查找路径,不新增 +# 语义:与手写 `T1: CTypedef = T2` 落到**同一条** typedef 注册/查找路径,不新增 # 第二套实现(TPC:符号表 SymbolTypeResolver._resolve_ctypedef_typedef → # _resolve_typedef_from_value;翻译期 HandlesAnnAssign / DeclarationGenerator 的 # typedef 表。VPC:AssignGenMixin.translate_annassign 的 CTypedef 分支 → # TypeGenCType.register_ctypedef)。RHS 即"类型表达式"(书写在值位): -# 裸名 `int32` / `t.X` / 并集 `t.CChar | t.CPtr` / 泛型 `array[E, N]` / 链式 `A = B`。 +# 裸名 `int32` / `X` / 并集 `CChar | CPtr` / 泛型 `array[E, N]` / 链式 `A = B`。 # # `typedef` 是**语句级保留字**:行首出现即必须是 `typedef 名字 = 类型` 形态。 -# - 合法形态:同行替换为 `名字: t.CTypedef = 类型`(不增删换行,行号映射保持有效, +# - 合法形态:同行替换为 `名字: CTypedef = 类型`(不增删换行,行号映射保持有效, # 与 fn/enum/define 同约定); # - 非法形态(`typedef = 1` / `typedef A` / `typedef A = ` 缺 RHS)⇒ **响亮失败** # (SyntaxError,非静默);`typedef A = 1`(RHS 不是类型)通过语法层,落到既有 @@ -307,7 +305,7 @@ _TYPEDEF_HEAD_RE: re.Pattern[str] = re.compile(r'^(\s*)typedef\b') def _ExpandTypedefs(Code: str) -> str: - """把 `typedef T1 = T2` 展开为等价的 `T1: t.CTypedef = T2`(行号不变)。 + """把 `typedef T1 = T2` 展开为等价的 `T1: CTypedef = T2`(行号不变)。 逐行处理:行终止符(LF/CRLF/CR)单独拆出后原样回写(与 _ExpandEnumBlocks / _ExpandDefineConsts 同约定,避免行尾 '\\r' 让 `$` 锚定的正则失配而**静默不展开**)。 @@ -325,13 +323,13 @@ def _ExpandTypedefs(Code: str) -> str: term: str = raw[k:] decl = _TYPEDEF_DECL_RE.match(body) if decl is not None: - out.append(f'{decl.group(1)}{decl.group(2)}: t.CTypedef ={decl.group(3)}{term}') + out.append(f'{decl.group(1)}{decl.group(2)}: CTypedef ={decl.group(3)}{term}') continue if _TYPEDEF_HEAD_RE.match(body) is not None: raise SyntaxError( f"typedef 语法错误(原文: {body.strip()!r}):应为 " - f"`typedef 名字 = 类型`(等价于 `名字: t.CTypedef = 类型`)。" - f"合法的类型写法:裸名 / t.X / a | t.CPtr / array[E, N] / 另一 typedef 名。" + f"`typedef 名字 = 类型`(等价于 `名字: CTypedef = 类型`)。" + f"合法的类型写法:裸名 / X / a | CPtr / array[E, N] / 另一 typedef 名。" ) out.append(raw) return ''.join(out) @@ -340,30 +338,30 @@ def _ExpandTypedefs(Code: str) -> str: # --------------------------------------------------------------------------- # 类型描述符 const / volatile(Viper 语法糖:描述符写在**类型前**) # --------------------------------------------------------------------------- -# const int → t.CConst | int -# volatile int → t.CVolatile | int -# const volatile int → t.CConst | t.CVolatile | int -# volatile const int → t.CVolatile | t.CConst | int(顺序任意,两个限定符都累积) -# const t.CInt32T → t.CConst | t.CInt32T -# const rawptr[Foo] → t.CConst | rawptr[Foo] (描述符只管注解最前面) -# a: const int → a: t.CConst | int (局部 / 类字段) -# def f(p: const int) → def f(p: t.CConst | int) (形参) -# def f() -> const int → ... -> t.CConst | int (返回) +# const int → CConst | int +# volatile int → CVolatile | int +# const volatile int → CConst | CVolatile | int +# volatile const int → CVolatile | CConst | int(顺序任意,两个限定符都累积) +# const CInt32T → CConst | CInt32T +# const rawptr[Foo] → CConst | rawptr[Foo] (描述符只管注解最前面) +# a: const int → a: CConst | int (局部 / 类字段) +# def f(p: const int) → def f(p: CConst | int) (形参) +# def f() -> const int → ... -> CConst | int (返回) # -# 语义:与**手写** `t.CConst | T` / `t.CVolatile | T` 逐点等价——**同一表示**, -# 不新造第二套(描述符不是新类型,只是 `|` 联合里的既有 flag 载体 t.CConst / -# t.CVolatile): +# 语义:与**手写** `CConst | T` / `CVolatile | T` 逐点等价——**同一表示**, +# 不新造第二套(描述符不是新类型,只是 `|` 联合里的既有 flag 载体 CConst / +# CVolatile): # - TPC:展开文本落到既有识别路径(HandlesTypeMerge.GetCTypeInfo 的 -# ModulePath=='t' 分支 → Info.DataConst/DataVolatile(HandlesTypeMerge.py:192-201); +# 内建限定符 → Info.DataConst/DataVolatile; # TypeAnnotationResolver 的类型限定符分支 → DataConst/DataVolatile # (TypeAnnotationResolver.py:934-938)),再由 _MergeCTypeInfoInto 累积 # (HandlesTypeMerge.py:1064-1071)、TypeAnnotationResolver.from_node 的 # BitOr 合并分支累积(TypeAnnotationResolver.py:626-633/640-674); # **BaseType 取非限定符一侧**(TypeAnnotationResolver.py:642-644),故 -# `t.CConst | int` 与 `int | t.CConst` 等价,本层统一产出**描述符在前** -# (与全仓既有真实写法一致:includes/stdio.vp:4 `fmt: t.CConst | str`、 -# includes/spinlock.vp:6 `locked: t.CVolatile | int`、 -# ViperApps/ViperOS/VKernel/Kernel/main.vp:301 `t.CConst | int | t.CPtr`)。 +# `CConst | int` 与 `int | CConst` 等价,本层统一产出**描述符在前** +# (与全仓既有真实写法一致:includes/stdio.vp:4 `fmt: CConst | str`、 +# includes/spinlock.vp:6 `locked: CVolatile | int`、 +# ViperApps/ViperOS/VKernel/Kernel/main.vp:301 `CConst | int | CPtr`)。 # - VPC:includes/ast/parser.vp 的 `_parse_type_ann` 合成**同形** AST # (BinOp(BitOr, Attribute(t,'CConst'), <类型>)),产出与手写形态逐字段同形。 # @@ -374,9 +372,9 @@ def _ExpandTypedefs(Code: str) -> str: # `名字: static 类型`(如旧的 `pack_head: static uint32 = 0`),必须改写为**语句 # 起始前置**形式——变量 `static 名字: 类型 = 值`、函数 `static def 名字(...)` # (见 _ExpandExportExternVar 的 static 前置分支与 vast.Parser._ParseStaticDef); -# 旧注解位置一律**响亮失败**(见下),不再脱糖为 `t.CStatic | T`。 +# 旧注解位置一律**响亮失败**(见下),不再脱糖为 `CStatic | T`。 # 非类型位置**原样保留**为普通标识符(不做词法保留字): -# - `t.attr.const()`(ViperC/Test/App/attr_test.vp:142,全仓 .vp 代码内唯一出现) +# - `attr.const()`(ViperC/Test/App/attr_test.vp:142,全仓 .vp 代码内唯一出现) # - `const = 5` / `x = const` / `d = {"k": const}` # 注释与字符串内容**不参与**:本层用 `tokenize` 做词法切分(不是行正则), # 故 openssl/*.vp 等 C 原型注释里的 `const char *`(全仓 275 处)逐字不变。 @@ -396,7 +394,7 @@ _DESCRIPTOR_HINT: str = ( '(可组合:`名字: const volatile 类型`)' ) _DESCRIPTOR_EXAMPLE: str = ( - 'a: const int / a: volatile int / a: const volatile t.CInt32T / ' + 'a: const int / a: volatile int / a: const volatile CInt32T / ' 'def f(p: const rawptr[Foo]) -> const int' ) @@ -442,7 +440,7 @@ def _StaticPositionSyntaxError(Lineno: int, Col: int, Snippet: str) -> SyntaxErr f"[TPC] 注解位置的 static 已不再支持:行 {Lineno} 列 {Col}," f"源码片段 {Snippet.strip()!r}。" f"请写成前置形式 `static 名字: 类型 = 值`" - f"(等价 `名字: t.CStatic | 类型 = 值`);" + f"(等价 `名字: CStatic | 类型 = 值`);" f"正确示例:`static memory_regions: memory_region* = None` / " f"`static pack_head: uint32 = 0`。" f"(旧写法 `名字: static 类型` 已删除,绝不静默改写)" @@ -455,13 +453,13 @@ _TYPEDEF_RHS_SCAN_LIMIT: int = 256 def _IsTypedefAnnotationRhs(Tokens: list, EqIdx: int) -> bool: """`EqIdx` 处的 `=` 是否是 `名字: <含 CTypedef 的注解> = <类型>` 的赋值号。 - 用途:把 `t.CTypedef` 注解的**右值**也纳入类型位置,使 - `LPCSTR: t.CTypedef = const str` / `= const uint16*` 里的描述符被展开 + 用途:把 `CTypedef` 注解的**右值**也纳入类型位置,使 + `LPCSTR: CTypedef = const str` / `= const uint16*` 里的描述符被展开 (与注解位同一展开规则;右值的 `T*` 后缀由 vast 的 _ParseTypeAnnotation 处理)。 判据:从 `=` 反向扫描到**深度 0 的 `:`**(跳过注释/NL,遇换行/`;` 即视为非声明行), 再确认 `:` 与 `=` 之间出现 NAME `CTypedef`。故 `x: int = const`(值恰为标识符 const)、 - `d = {"k": const}`、`f = lambda x: t.CTypedef` 等一律不受影响。 + `d = {"k": const}`、`f = lambda x: CTypedef` 等一律不受影响。 """ if EqIdx < 0 or EqIdx >= len(Tokens): return False @@ -529,7 +527,7 @@ def _InStaticOldAnnotationPosition(Tokens: list, Index: int) -> bool: # C-style leading array declarator `const [N]T`: textual desugar into -# `t.CArray[T, N]` (same shape as VPC includes/ast/parser.vp:_parse_array_prefix_declarator). +# `CArray[T, N]` (same shape as VPC includes/ast/parser.vp:_parse_array_prefix_declarator). _TYPE_BRACKET_OPENERS: frozenset[str] = frozenset({'(', '[', '{'}) _TYPE_BRACKET_CLOSERS: frozenset[str] = frozenset({')', ']', '}'}) # Annotation type expression ends at these top-level operators. @@ -548,8 +546,8 @@ def _ScanAnnotationTypeEnd(Tokens: list, Start: int, Count: int) -> int: Tok = Tokens[k] if Tok.type == tokenize.COMMENT: # 行尾注释不属于类型文本。若当普通注释跳过继续扫,ElemEnd - 1 会落到注释上, - # 使数组前缀脱糖把注释并进 `t.CArray[...]` 内部(`data: [512]uint8 # 注释` - # 会变成 `t.CArray[uint8 # 注释, 512]` ⇒ 方括号失衡、整段注解作废)。 + # 使数组前缀脱糖把注释并进 `CArray[...]` 内部(`data: [512]uint8 # 注释` + # 会变成 `CArray[uint8 # 注释, 512]` ⇒ 方括号失衡、整段注解作废)。 break if Tok.type in _DESCRIPTOR_SKIP_TYPES: k += 1 @@ -571,7 +569,7 @@ def _ScanAnnotationTypeEnd(Tokens: list, Start: int, Count: int) -> int: def _DesugarArrayPrefix(Tokens: list, BracketIdx: int, Count: int, Code: str) -> tuple[int, str] | None: - """Desugar a leading array prefix `[N]...T` into the text `t.CArray[T, N]`. + """Desugar a leading array prefix `[N]...T` into the text `CArray[T, N]`. `Tokens[BracketIdx]` is '['. Returns `(End, TypeText)` where End is the index just past the element type. Supports `[N][M]T` (outer-to-inner) and `[]T` @@ -620,12 +618,12 @@ def _DesugarArrayPrefix(Tokens: list, BracketIdx: int, Count: int, ElemText: str = Lines0[Line - 1][Tokens[ElemStart].start[1]:Tokens[ElemEnd - 1].end[1]] Result: str = ElemText for GroupText in reversed(Groups): # inner first (right-to-left) - Result = f't.CArray[{Result}, {GroupText}]' + Result = f'CArray[{Result}, {GroupText}]' return ElemEnd, Result # Bare C-style leading array declarator `[N]T` / `[]T` at annotation positions (no -# descriptor), desugared to `t.CArray[T, N]` / `t.CArray[T, None]` — same shape as the +# descriptor), desugared to `CArray[T, N]` / `CArray[T, None]` — same shape as the # const/volatile path and VPC _parse_array_prefix_declarator. _ARRAY_PREFIX_HINT: str = ( '`名字: [长度]元素类型`(长度可省略:`[]元素类型`);' @@ -691,9 +689,9 @@ def _AtAnnotationColon(Tokens: list, ColonIdx: int, Stack: list) -> bool: # 注解位置。本判据必须在修饰符展开**之前**成立——`[N]T` 数组前缀与 # `__attribute__(...)` 两条路径都先于该展开运行,靠它把 # `export gdt: [7]gdt_entry = []` / `static g: [7]int = []` 正常脱糖成 - # `t.CArray[...]` 形态(若等到展开后再插入 ` | t.CExport` / 前置 `t.CStatic | `, + # `CArray[...]` 形态(若等到展开后再插入 ` | CExport` / 前置 `CStatic | `, # `|` 不在 _TYPE_EXPR_STOP_TOKENS 中,会被并进数组元素类型 → - # `t.CArray[gdt_entry | t.CExport, 7]`)。 + # `CArray[gdt_entry | CExport, 7]`)。 if Bound.type == tokenize.NAME and Bound.string in _EXPORT_EXTERN_MODIFIERS: return True return Bound.type in _ARRAY_STMT_BOUNDARY or Bound.string == ';' @@ -743,7 +741,7 @@ def _ApplySameLineEdits(Code: str, Edits: list[tuple[int, int, int, str, str]]) def _ExpandArrayPrefixAnnotations(Code: str) -> str: - """Desugar bare `[N]T` array-prefix annotations into `t.CArray[T, N]` (same line). + """Desugar bare `[N]T` array-prefix annotations into `CArray[T, N]` (same line). Only fires when '[' sits at an annotation position (see _InArrayAnnotationPosition); right-hand list literals are never touched. A '[' at an annotation position that @@ -790,16 +788,16 @@ def _ExpandArrayPrefixAnnotations(Code: str) -> str: # --------------------------------------------------------------------------- # 变量声明的存储类修饰符 export / extern / static(语句级软关键字)——与 VPC # includes/ast/parser.vp **同一标记、同一消费路径**: -# export 名字: T [= 初值] → 名字: T | t.CExport [= 初值] +# export 名字: T [= 初值] → 名字: T | CExport [= 初值] # (本模块**定义**:定义端裸名,不加模块 SHA1 头;内联汇编 / C 符号对接必需。 # 无初值时按既有零初始化全局定义处理,如 `export tss_buf: [104]uint8`。) -# extern 名字: T → 名字: T | t.State -# (**仅声明**:t.State = t.CExtern | t.CExport ⇒ 定义端 `@裸名 = external global T`。 +# extern 名字: T → 名字: T | State +# (**仅声明**:State = CExtern | CExport ⇒ 定义端 `@裸名 = external global T`。 # extern 是外部定义,**不允许**初值 ⇒ 带 `= 初值` 一律终止编译。) -# static 名字: T [= 初值] → 名字: t.CStatic | T [= 初值] +# static 名字: T [= 初值] → 名字: CStatic | T [= 初值] # (存储类标记**前置**在类型联合最左,与 VPC `_ParseStaticModified` 的 -# `pending_static` 通道同源——`static 名字: T` → `名字: t.CStatic | T`;允许初值。 -# 产出与手写 `名字: t.CStatic | T` / 装饰器 `@t.CStatic` 逐字段同形。 +# `pending_static` 通道同源——`static 名字: T` → `名字: CStatic | T`;允许初值。 +# 产出与手写 `名字: CStatic | T` / 装饰器 `@CStatic` 逐字段同形。 # 旧注解位置写法 `名字: static T` 已删除,见 _StaticPositionSyntaxError。) # 与函数形态(`export def f()` / `export f()` / `extern def f()` / `static def f()`, # vast 既有处理)由第三个 token 区分:`:` 是变量,`(` / `[` 是函数 ⇒ 函数语义逐字不变。 @@ -807,9 +805,9 @@ def _ExpandArrayPrefixAnnotations(Code: str) -> str: # --------------------------------------------------------------------------- _EXPORT_EXTERN_MODIFIERS: frozenset[str] = frozenset({'export', 'extern', 'static'}) _EXPORT_EXTERN_HINT: str = ( - '`export 名字: 类型 [= 初值]`(裸名导出,等价 `名字: 类型 | t.CExport`);' - '`extern 名字: 类型`(仅声明,等价 `名字: 类型 | t.State`,**不允许初值**);' - '`static 名字: 类型 [= 初值]`(等价 `名字: t.CStatic | 类型`)' + '`export 名字: 类型 [= 初值]`(裸名导出,等价 `名字: 类型 | CExport`);' + '`extern 名字: 类型`(仅声明,等价 `名字: 类型 | State`,**不允许初值**);' + '`static 名字: 类型 [= 初值]`(等价 `名字: CStatic | 类型`)' ) _EXPORT_EXTERN_EXAMPLE: str = ( 'export gdt: [7]gdt_entry = [] / export tss_buf: [104]uint8 / extern a: int / ' @@ -832,19 +830,19 @@ def _ExpandExportExternVar(Code: str) -> str: """把 `export 名字: T [= 初值]` / `extern 名字: T` / `static 名字: T [= 初值]` 展开为带存储类标记的注解。 - 与 VPC 同口径:export → 类型**右侧追加** `| t.CExport`;extern → 追加 `| t.State` - (extern 带初值 ⇒ **响亮失败** SyntaxError);static → 类型**左侧前置** `t.CStatic | ` + 与 VPC 同口径:export → 类型**右侧追加** `| CExport`;extern → 追加 `| State` + (extern 带初值 ⇒ **响亮失败** SyntaxError);static → 类型**左侧前置** `CStatic | ` (与 ViperC `_ParseStaticModified` / `pending_static` 通道同源——`static 名字: T` - → `名字: t.CStatic | T`,亦与手写 `名字: t.CStatic | T` / `@t.CStatic` 逐字段同形; + → `名字: CStatic | T`,亦与手写 `名字: CStatic | T` / `@CStatic` 逐字段同形; static **允许**初值)。 - 只在"语句起始(可缩进)+ export/extern/static + 标识符 + `:`"形态触发;函数形态 (`export def f()` / `export f()` / `extern def f()` / `static def f()`)第三个 token 不是 `:` ⇒ 不命中,vast 的既有函数处理逐字不变。 - **必须排在 `_ExpandArrayPrefixAnnotations` 之后**:此时注解已是规范形态 - (`t.CArray[T, N]` / `t.CConst | ...`),插入点由 `_ScanAnnotationTypeEnd` + (`CArray[T, N]` / `CConst | ...`),插入点由 `_ScanAnnotationTypeEnd` 确定;`|` 不在 `_TYPE_EXPR_STOP_TOKENS` 中,若在数组前缀展开前插入会被 - 并进数组元素类型(`t.CArray[gdt_entry | t.CExport, 7]`)。数组前缀之所以 + 并进数组元素类型(`CArray[gdt_entry | CExport, 7]`)。数组前缀之所以 仍能脱糖,靠的是 `_AtAnnotationColon` 已把 export/extern/static 认作语句边界。 - 同行编辑(删修饰符 + 插/前置标记),不增删换行 ⇒ 行号映射保持有效。 """ @@ -893,15 +891,15 @@ def _ExpandExportExternVar(Code: str) -> str: if IsStatic: # 编辑 2(static):存储类标记**前置**在类型左侧(联合最左)。 # 与 ViperC `_ParseStaticModified` / `pending_static` 通道 - # 逐字同形:`static 名字: T` → `名字: t.CStatic | T`,产出与 - # 手写 `名字: t.CStatic | T` / `@t.CStatic` 逐字段同形。 + # 逐字同形:`static 名字: T` → `名字: CStatic | T`,产出与 + # 手写 `名字: CStatic | T` / `@CStatic` 逐字段同形。 InsAt: tuple[int, int] = Tokens[TypeStart].start - Edits.append((InsAt[0], InsAt[1], InsAt[1], 't.CStatic | ', '')) + Edits.append((InsAt[0], InsAt[1], InsAt[1], 'CStatic | ', '')) else: # 编辑 2(export/extern):存储类标记**追加**在注解类型终点 - # (右侧):export → `| t.CExport`;extern → `| t.State`。 + # (右侧):export → `| CExport`;extern → `| State`。 InsAt = Tokens[TypeEnd - 1].end - Marker: str = ' | t.State' if IsExtern else ' | t.CExport' + Marker: str = ' | State' if IsExtern else ' | CExport' Edits.append((InsAt[0], InsAt[1], InsAt[1], Marker, '')) i = TypeEnd continue @@ -916,17 +914,17 @@ def _ExpandExportExternVar(Code: str) -> str: # includes/ast/parser.vp 的 _IsMagicAttributeCall / _MakeTAttrMarker 同源书写法, # TPC 侧在本层文本脱糖;与 const/volatile、`[N]T` 数组前缀同属一套语法糖): # V: __attribute__(section(".PRVERSN")) []char = "0.0.3-dev.428" -# → V: t.attr.section(".PRVERSN") | t.CArray[char, None] = "0.0.3-dev.428" +# → V: attr.section(".PRVERSN") | CArray[char, None] = "0.0.3-dev.428" # x: __attribute__(aligned(16)) int = 0 -# → x: t.attr.aligned(16) | int = 0 -# 脱糖目标与手写 `T | t.attr.X(...)`(HandlesAssign 的模块级全局 t.attr.* 分支 +# → x: attr.aligned(16) | int = 0 +# 脱糖目标与手写 `T | attr.X(...)`(HandlesAssign 的模块级全局 attr.* 分支 # 所认的形态)逐字同形,故下游 AnnotationLoader / HandlesAssign / # DeclarationGenerator 零新增判据。 -# `t.CArray[T, None]` = TPC 的"长度自动推导数组"(HandlesAssign.py:1606), +# `CArray[T, None]` = TPC 的"长度自动推导数组"(HandlesAssign.py:1606), # 恰是 `[]char` 的语义。 # --------------------------------------------------------------------------- _ATTRIBUTE_CALLEE: str = '__attribute__' -_ATTR_MARKER_PREFIX: str = 't.attr.' +_ATTR_MARKER_PREFIX: str = 'attr.' _ATTRIBUTE_DESCRIPTOR_HINT: str = ( '`名字: __attribute__(section(".text")) 类型`(形参 / 返回值同样成立,' '可与 const/volatile 混写,其后可接 C 风格数组前缀 `[N]T` / `[]T`)' @@ -966,9 +964,9 @@ def _MatchOpenBracket(Tokens: list, CloseIdx: int) -> int: def _AttributeMarkerText(ArgText: str) -> str: """`__attribute__` 单个实参文本 → 描述符文本(与 VPC _MakeTAttrMarker 同口径)。 - - 裸名 `always_inline` → `t.attr.always_inline` - - 调用 `section(".text")` → `t.attr.section(".text")` - - 其余(已含点的 `t.attr.X` / `c.Attribute(...)`)→ 原样保留(允许混写) + - 裸名 `always_inline` → `attr.always_inline` + - 调用 `section(".text")` → `attr.section(".text")` + - 其余(已含点的 `attr.X` / `Attribute(...)`)→ 原样保留(允许混写) """ T: str = (ArgText or '').strip() if not T: @@ -1024,7 +1022,7 @@ def _InAttributeAnnotationPosition(Tokens: list, Index: int, Stack: list) -> boo def _ExpandAttributeDescriptors(Code: str) -> str: - """把注解位置的 `__attribute__(...)` 脱糖为 `t.attr.<名>` 描述符(同行替换)。 + """把注解位置的 `__attribute__(...)` 脱糖为 `attr.<名>` 描述符(同行替换)。 规则与示例见上方常量块注释。紧跟的 C 风格前置数组前缀 `[N]T` / `[]T` 在**同一次 编辑**里一并脱糖(`_DesugarArrayPrefix`,已支持空长度 ⇒ `None`)——否则 `[]char` @@ -1148,11 +1146,11 @@ def _ExpandAttributeDescriptors(Code: str) -> str: def _ExpandTypeDescriptors(Code: str) -> str: - """把 `const T` / `volatile T`(含组合、任意顺序)展开为 `t.CConst | T` 等形态(行号不变)。 + """把 `const T` / `volatile T`(含组合、任意顺序)展开为 `CConst | T` 等形态(行号不变)。 - 词法级切分(`tokenize`):注释/字符串内容天然不参与,不会被误改写。 - 只在"注解位置"(前一个 token 是 `:` 且再前一个是 Name,或前一个 token 是 `->`, - 或 `名字: t.CTypedef =` 的赋值号右侧,见 _IsTypedefAnnotationRhs) + 或 `名字: CTypedef =` 的赋值号右侧,见 _IsTypedefAnnotationRhs) 识别描述符串;非类型位置原样保留为普通标识符(软关键字边界)。 - **`static` 不再属于本展开器**(已迁出注解位置):注解位置出现 `static` (如 `memory_regions: static memory_region* = None`)一律**响亮失败** @@ -1163,7 +1161,7 @@ def _ExpandTypeDescriptors(Code: str) -> str: - 词法失败(未闭合字符串等)时原样返回:该输入在后续 ast.parse 处必然响亮失败, 本层不新增第二套错误通道(不静默丢描述符:词法都没过,描述符根本没被识别为描述符)。 - `const [N]T` (C-style leading array prefix) desugars to - `t.CConst | t.CArray[T, N]`; see _DesugarArrayPrefix. + `CConst | CArray[T, N]`; see _DesugarArrayPrefix. """ if 'const' not in Code and 'volatile' not in Code and 'static' not in Code: return Code @@ -1205,7 +1203,7 @@ def _ExpandTypeDescriptors(Code: str) -> str: if BeforePrevIdx >= 0 and Tokens[BeforePrevIdx].type == tokenize.NAME: InAnnotationPosition = True elif Prev.string == '=' and _IsTypedefAnnotationRhs(Tokens, PrevIdx): - # `LPCSTR: t.CTypedef = const str`:typedef 的右值也是类型位置 + # `LPCSTR: CTypedef = const str`:typedef 的右值也是类型位置 # (与 VPC 的 _parse_type_ann 右值分支同口径)。 InAnnotationPosition = True if InAnnotationPosition: @@ -1218,14 +1216,14 @@ def _ExpandTypeDescriptors(Code: str) -> str: if Next is not None and Next.type == tokenize.OP and Next.string == '[': # `const [N]T` / `volatile [N]T` / `const volatile [N]T`: TPC vast has # no `[N]T`; desugar the array prefix together with the descriptor into - # `t.CConst | t.CArray[T, N]` (same shape as VPC). + # `CConst | CArray[T, N]` (same shape as VPC). Desugared = _DesugarArrayPrefix(Tokens, j, n, Code) if Desugared is not None: End, ArrayText = Desugared First = Run[0] Line0: str = Code.splitlines()[First.start[0] - 1] Text: str = ' | '.join( - f't.{_TYPE_DESCRIPTOR_MARKERS[m.string]}' for m in Run + f'{_TYPE_DESCRIPTOR_MARKERS[m.string]}' for m in Run ) + f' | {ArrayText}' Edits.append((First.start[0], First.start[1], Tokens[End - 1].end[1], Text, @@ -1235,7 +1233,7 @@ def _ExpandTypeDescriptors(Code: str) -> str: # Not a valid array prefix: fall through to the fail-fast below. if Next is not None and Next.type == tokenize.NAME: Text: str = ' | '.join( - f't.{_TYPE_DESCRIPTOR_MARKERS[m.string]}' for m in Run) + ' |' + f'{_TYPE_DESCRIPTOR_MARKERS[m.string]}' for m in Run) + ' |' Edits.append((Run[0].start[0], Run[0].start[1], Run[-1].end[1], Text, Code.splitlines()[Run[0].start[0] - 1] [Run[0].start[1]:Run[-1].end[1]])) @@ -1253,7 +1251,7 @@ def _ExpandTypeDescriptors(Code: str) -> str: Code.splitlines()[First.start[0] - 1]) else: # 非注解位置:仅"整条语句恰好是一个描述符串"(裸用)才响亮失败, - # 其余(t.attr.const() / const = 5 / x = const …)按普通标识符原样保留。 + # 其余(attr.const() / const = 5 / x = const …)按普通标识符原样保留。 AtStmtStart: bool = Prev is None or Prev.type in ( tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT) AtStmtEnd: bool = Next is None or Next.type in ( @@ -1277,21 +1275,21 @@ def _ExpandTypeDescriptors(Code: str) -> str: # 的唯一同口径规则源,对照表见 Debugger/enum-semantics.md。 # --------------------------------------------------------------------------- # 规则: -# 无注解 / `t.State` 标记注解 → "无整数成员"口径(枚举宽度回落默认 32) +# 无注解 / `State` 标记注解 → "无整数成员"口径(枚举宽度回落默认 32) # 整数类型注解 → 按该类型位宽参与"取最宽"(见 EnumClassIntWidth) -# `bool` / `t.CBool` → **8**(枚举侧口径):枚举存储必须是可按字节寻址的 +# `bool` / `CBool` → **8**(枚举侧口径):枚举存储必须是可按字节寻址的 # 整数类型,`i1` 不能作为独立枚举宽度;本口径只作用于"枚举成员注解" # 这一处,**不改** TPC 全局 `bool`→`i8`(LLVMTypeMapper.py:174)与 # VPC 全局 `bool`→`i1`(TypeGenResolve.vp:2201-2203)的各自的全局语义。 -# TPC 侧 `bool` 经 BuiltinTypeMap → `t.CBool.Size == 8` 天然成立 -# (t.CBool 同 8),故本文件不另加硬编码分支。 +# TPC 侧 `bool` 经 BuiltinTypeMap → `CBool.Size == 8` 天然成立 +# (CBool 同 8),故本文件不另加硬编码分支。 # 指针注解 → 在成员注册处明确报错(本文件与 ClassGenEnum 的 ptr 拦截) # 其余(无法解析 / 非整数:float/void/struct…)→ 视为"无整数成员" # (不引入新的硬失败;VPC 侧更严,对"有注解但解析失败"是 fatal,差异已记录) _ENUM_DEFAULT_INT_WIDTH: int = 32 # State 标记名(与 VPC ClassGenEnum._is_state_annotation 同集合):该注解只是 -# `t.CEnum` 成员的存在性标记,不携带宽度语义。 +# `CEnum` 成员的存在性标记,不携带宽度语义。 _ENUM_STATE_MARKER_NAMES: frozenset[str] = frozenset({'State'}) @@ -1322,7 +1320,7 @@ def EnumIntWidth(Info: object | None, Default: int = _ENUM_DEFAULT_INT_WIDTH) -> def IsEnumStateMarker(Annotation: object | None) -> bool: - """注解节点是否为 `t.State` / `State`(枚举默认成员的存在性标记)。""" + """注解节点是否为 `State` / `State`(枚举默认成员的存在性标记)。""" if Annotation is None: return False if isinstance(Annotation, ast.Attribute): @@ -1333,7 +1331,7 @@ def IsEnumStateMarker(Annotation: object | None) -> bool: def _EnumAnnotationSimpleName(Annotation: object | None) -> str | None: - """注解节点的"顶名":`t.CInt64T` → 'CInt64T'、`int64` → 'int64';其余 → None。""" + """注解节点的"顶名":`CInt64T` → 'CInt64T'、`int64` → 'int64';其余 → None。""" if isinstance(Annotation, ast.Attribute): return Annotation.attr if isinstance(Annotation, ast.Name): @@ -1351,19 +1349,19 @@ def _IntSizeOf(BaseType: object | None) -> int | None: def _EnumTypeStrToClass(Text: str | None) -> type | None: - """builtins typedef 值(`t.CInt64T` / `CInt64T`)→ t 模块类型类;其余 → None。 + """builtins typedef 值(`CInt64T` / `CInt64T`)→ 内建类型类;其余 → None。 - 供"无 SymbolTable 的声明端"把 int8/int64/… 归一到 t 类型类取位宽。 + 供"无 SymbolTable 的声明端"把 int8/int64/… 归一到内建类型类取位宽。 """ if not Text: return None Name: str = Text.strip() - if Name.startswith('t.') or Name.startswith('c.'): - Name = Name[2:] if not Name or not Name.isidentifier(): return None - Cls = getattr(t, Name, None) - if isinstance(Cls, type) and issubclass(Cls, t.CType) and Cls is not t.CType: + Cls = getattr(TypeSystem, Name, None) + if Cls is None: + Cls = TypeSystem.BUILTIN_TYPE_ALIASES.get(Name) + if isinstance(Cls, type) and issubclass(Cls, TypeSystem.CType) and Cls is not TypeSystem.CType: return Cls return None @@ -1372,7 +1370,7 @@ def EnumMemberAnnotationIntWidth(Annotation: object | None, SymbolTable: object | None = None) -> int | None: """枚举成员注解 → 整数位宽(bit);None = "默认口径"(走 _ENUM_DEFAULT_INT_WIDTH)。 - `t.State` 标记或无注解 → None;整数类型(`int`/`char`/`C*` 家族 / builtins + `State` 标记或无注解 → None;整数类型(`int`/`char`/`C*` 家族 / builtins 与库 typedef)→ 其 `Size`;无法解析或非整数(float/void/struct…)→ None (默认 32,与改前行为一致,不引入新的硬失败)。指针形态由调用方在解析前 拦截(HandlesClassDef._EnumMemberAnnotationIsPtr / VPC 的 @@ -1389,8 +1387,8 @@ def EnumMemberAnnotationIntWidth(Annotation: object | None, return None Name = _EnumAnnotationSimpleName(Annotation) if Name is not None: - Cls = getattr(t, Name, None) - if isinstance(Cls, type) and issubclass(Cls, t.CType) and Cls is not t.CType: + Cls = getattr(TypeSystem, Name, None) + if isinstance(Cls, type) and issubclass(Cls, TypeSystem.CType) and Cls is not TypeSystem.CType: try: Width = _IntSizeOf(Cls()) except Exception: @@ -1580,34 +1578,34 @@ def ExpandSoftKeywords(Code: str) -> str: 1) fn/fun/func/function → def(函数定义行):仅在"行首缩进 + 关键字 + 空白 + 标识符"的函数定义形态匹配,变量名(fn = 5)、调用(fn(x))、注解(x: fn) 与字符串内容不受影响。 - 2) `enum Name:` 块 → `class Name(t.CEnum):` 块(裸成员补 `: t.State`): + 2) `enum Name:` 块 → `class Name(CEnum):` 块(裸成员补 `: State`): 与手写继承式枚举产出**同一 AST**,故语义(默认编号 0..N、自定义成员类型、 宽度取最宽成员)完全一致。 - 3) `define NAME[: T] = 值` → `NAME: [T |] t.CDefine = 值`:编译期常量声明, - 与手写 `NAME: t.CDefine = 值` 产出**同一 AST/同一注册路径**(见 + 3) `define NAME[: T] = 值` → `NAME: [T |] CDefine = 值`:编译期常量声明, + 与手写 `NAME: CDefine = 值` 产出**同一 AST/同一注册路径**(见 _ExpandDefineConsts)。`define NAME(...)`(宏函数)不受影响。 - 4) `typedef T1 = T2` → `T1: t.CTypedef = T2`:类型别名声明,与手写 - `T1: t.CTypedef = T2` 产出**同一 AST/同一注册路径**(见 _ExpandTypedefs)。 + 4) `typedef T1 = T2` → `T1: CTypedef = T2`:类型别名声明,与手写 + `T1: CTypedef = T2` 产出**同一 AST/同一注册路径**(见 _ExpandTypedefs)。 行首 `typedef` 的非声明形态**响亮失败**(该词不在任何既有源码中作标识符)。 - 5) 类型描述符 `const T` / `volatile T` → `t.CConst | T` / `t.CVolatile | T`: - 与手写 `t.CConst | T` 产出**同一 AST/同一解析路径**(见 _ExpandTypeDescriptors)。 - 只在注解位置生效的软关键字(`t.attr.const()` 等非类型位置原样保留); + 5) 类型描述符 `const T` / `volatile T` → `CConst | T` / `CVolatile | T`: + 与手写 `CConst | T` 产出**同一 AST/同一解析路径**(见 _ExpandTypeDescriptors)。 + 只在注解位置生效的软关键字(`attr.const()` 等非类型位置原样保留); 缺类型 / 后随非类型 / 裸用**响亮失败**(SyntaxError)。`static` 已从注解位置 迁出——注解位置出现 `static`(`名字: static 类型`)**响亮失败**。 - 6) `union NAME:` → `class NAME(t.CUnion):`:与手写 `class NAME(t.CUnion):` 产出 + 6) `union NAME:` → `class NAME(CUnion):`:与手写 `class NAME(CUnion):` 产出 **同一 AST/同一注册路径**(见 _ExpandUnionBlocks)。成员为普通注解字段。 行首 `union` 的非 `union 名字:` 形态**响亮失败**(该词不在任何源码中作标识符)。 - 7) 裸数组前缀 `[N]T` / `[]T` → `t.CArray[T, N]` / `t.CArray[T, None]`(见 + 7) 裸数组前缀 `[N]T` / `[]T` → `CArray[T, N]` / `CArray[T, None]`(见 _ExpandArrayPrefixAnnotations):只在注解位置生效(AnnAssign 的 ':' 之后 / 形参 / '->' 之后 / 类字段),右值列表字面量**绝不改动**;无法脱糖的注解位置 数组前缀**响亮失败**(SyntaxError,绝不静默产出 List 注解)。 - 8) `renum NAME:` → `class NAME(t.REnum):`:与手写 `class NAME(t.REnum):` 产出 + 8) `renum NAME:` → `class NAME(REnum):`:与手写 `class NAME(REnum):` 产出 **同一 AST/同一注册路径**(见 _ExpandRenumBlocks)。成员为普通类体(嵌套 `class 变体:` + 无载荷赋值)。行首 `renum` 的非 `renum 名字:` 形态**响亮失败** (该词不在任何源码中作标识符)。 - 9) `export 名字: T [= 初值]` → `名字: T | t.CExport [= 初值]`; - `extern 名字: T` → `名字: T | t.State`;`static 名字: T [= 初值]` → - `名字: t.CStatic | T [= 初值]`(见 _ExpandExportExternVar)。 + 9) `export 名字: T [= 初值]` → `名字: T | CExport [= 初值]`; + `extern 名字: T` → `名字: T | State`;`static 名字: T [= 初值]` → + `名字: CStatic | T [= 初值]`(见 _ExpandExportExternVar)。 与 VPC 同一标记、同一消费路径;export/extern 在类型右侧追加标记,static 在 类型左侧前置标记(与 VPC `_ParseStaticModified` 的 `pending_static` 同源); 函数形态(`export def f()` / `export f()` / `extern def f()` / `static def f()`, @@ -1647,11 +1645,11 @@ def _ExpandSoftKeywordsImpl(Code: str) -> str: if 'typedef' in Code: Code = _ExpandTypedefs(Code) # 描述符放在最后:先让语句级语法糖(enum/union/define/typedef)落到规范形态, - # 本层再看规范注解(如 `define X: const int = 1` → `X: const int | t.CDefine = 1` - # → `X: t.CConst | int | t.CDefine = 1`,两种顺序结果相同)。 + # 本层再看规范注解(如 `define X: const int = 1` → `X: const int | CDefine = 1` + # → `X: CConst | int | CDefine = 1`,两种顺序结果相同)。 # `__attribute__(...)` 排在 const/volatile 之前:其注解位置判据需能回溯到**原始** - # 描述符串(`const __attribute__(x) int` 的 `const` 尚未被改写为 `t.CConst |`), - # 且它自身产出的 `t.attr.X |` 不会干扰紧随的 const/volatile 展开。 + # 描述符串(`const __attribute__(x) int` 的 `const` 尚未被改写为 `CConst |`), + # 且它自身产出的 `attr.X |` 不会干扰紧随的 const/volatile 展开。 if _ATTRIBUTE_CALLEE in Code: Code = _ExpandAttributeDescriptors(Code) # const/volatile 是注解位置的存储类描述符;`static` 已从注解位置迁出为**前置** @@ -1660,13 +1658,13 @@ def _ExpandSoftKeywordsImpl(Code: str) -> str: if 'const' in Code or 'volatile' in Code or 'static' in Code: Code = _ExpandTypeDescriptors(Code) # 裸 `[N]T` 数组前缀在描述符之后:`const [N]T` 已由 _ExpandTypeDescriptors 消化为 - # `t.CConst | t.CArray[T, N]`(此处不再有注解位置的裸 '['),避免两条路径重复改写。 + # `CConst | CArray[T, N]`(此处不再有注解位置的裸 '['),避免两条路径重复改写。 if '[' in Code: Code = _ExpandArrayPrefixAnnotations(Code) # export / extern / static 变量声明(语句级软关键字):必须排在**最后**——此时注解 - # 已由数组前缀 / 描述符两层脱糖成规范形态(`t.CArray[T, N]` / `t.CConst | ...`), - # 本层只删修饰符 + 插入存储类标记(export/extern 右追加 `| t.CExport` / `| t.State`; - # static 左前置 `t.CStatic | `)。顺序若反过来,`|` 会被数组前缀展开并进元素类型 + # 已由数组前缀 / 描述符两层脱糖成规范形态(`CArray[T, N]` / `CConst | ...`), + # 本层只删修饰符 + 插入存储类标记(export/extern 右追加 `| CExport` / `| State`; + # static 左前置 `CStatic | `)。顺序若反过来,`|` 会被数组前缀展开并进元素类型 # (见 _ExpandExportExternVar)。 if 'export' in Code or 'extern' in Code or 'static' in Code: Code = _ExpandExportExternVar(Code) @@ -1674,8 +1672,8 @@ def _ExpandSoftKeywordsImpl(Code: str) -> str: # --------------------------------------------------------------------------- -# t.CDefine 编译期整数常量的"可存储范围 + 宽度规则"判定——唯一规则源 -# (`define` 与手写 `X: t.CDefine = 值` 共用同一判据;对照表见 +# CDefine 编译期整数常量的"可存储范围 + 宽度规则"判定——唯一规则源 +# (`define` 与手写 `X: CDefine = 值` 共用同一判据;对照表见 # Debugger/define-constants.md) # --------------------------------------------------------------------------- # 规则: @@ -1684,7 +1682,7 @@ def _ExpandSoftKeywordsImpl(Code: str) -> str: # 解释"合并为 [-2^63, 2^64-1]。这与既有位模式惯用法一致(0xFFFFFFFF 落 i32 # 的 -1、0xA5A5A5A5A5A5A5A5 落 i64 负数,见 includes/memhub.vp:123 与 # LLVMCG/TypeConvert.py:181-186、HandlesExprAttr.py:163-173)。 -# ② 显式类型注解(`define NAME: T = 值` ⇒ `NAME: T | t.CDefine = 值`)另行要求 +# ② 显式类型注解(`define NAME: T = 值` ⇒ `NAME: T | CDefine = 值`)另行要求 # 值能落进 T 的**位宽** w:接受 [-(2^(w-1)), 2^w - 1](同样按"两种解释" # 惯例,`define X: int = 0xFFFFFFFF` 与 `= -1` 均合法);超出位宽必须报错。 # ③ 判据基于**精确值**(任意精度整数:字面量原值或 ConstEvaluator 的求值结果), @@ -1707,7 +1705,7 @@ DEFINE_STORE_MAX: int = (1 << 64) - 1 DEFINE_WIDTH_LADDER: tuple[int, ...] = (8, 16, 32, 64) # 报文用:可用整数类型清单(与 EnumMemberAnnotationIntWidth 的类型解析口径同源) _DEFINE_INT_TYPE_HINT: str = ( - 't.CInt8T/t.CUInt8T、t.CInt16T/t.CUInt16T、t.CInt32T/t.CUInt32T、t.CInt64T/t.CUInt64T' + 'CInt8T/CUInt8T、CInt16T/CUInt16T、CInt32T/CUInt32T、CInt64T/CUInt64T' '(或 builtins 的 int8/uint8/int16/uint16/int32/uint32/int64/uint64、char、sizet)' ) @@ -1752,7 +1750,7 @@ def DefineMinWidth(Value: object) -> int | None: def IsCDefineMarker(BaseType: object | None) -> bool: - """BaseType 是否为 t.CDefine 标记本身("未声明具体类型"的自动推导形态)。 + """BaseType 是否为 CDefine 标记本身("未声明具体类型"的自动推导形态)。 兼容 HandlesTypeMerge 把**类型类**直接放进 BaseType 的形态 (`Info.BaseType = TypeClass`,HandlesTypeMerge.py:228-234)。 @@ -1760,8 +1758,8 @@ def IsCDefineMarker(BaseType: object | None) -> bool: if BaseType is None: return False if isinstance(BaseType, type): - return issubclass(BaseType, t.CDefine) - return isinstance(BaseType, t.CDefine) + return issubclass(BaseType, TypeSystem.CDefine) + return isinstance(BaseType, TypeSystem.CDefine) def DefineIntWidthOf(BaseType: object | None) -> int | None: @@ -1775,8 +1773,8 @@ def DefineIntWidthOf(BaseType: object | None) -> int | None: Width: int | None = _IntSizeOf(BaseType) if Width is not None: return Width - if (isinstance(BaseType, type) and issubclass(BaseType, t.CType) - and BaseType is not t.CType): + if (isinstance(BaseType, type) and issubclass(BaseType, TypeSystem.CType) + and BaseType is not TypeSystem.CType): try: return _IntSizeOf(BaseType()) except Exception: @@ -1794,7 +1792,7 @@ def DefineIntSignednessOf(BaseType: object | None) -> bool | None: v: object | None = getattr(BaseType, 'IsSigned', None) if v is not None: return bool(v) - if isinstance(BaseType, type) and issubclass(BaseType, t.CType) and BaseType is not t.CType: + if isinstance(BaseType, type) and issubclass(BaseType, TypeSystem.CType) and BaseType is not TypeSystem.CType: try: inst: object = BaseType() except Exception: @@ -1804,7 +1802,7 @@ def DefineIntSignednessOf(BaseType: object | None) -> bool | None: return None -# CDefine 注解里参与"类型"判定的 t 标记(联合写法 `T | t.CDefine`、`T | t.State` 等): +# CDefine 注解里参与"类型"判定的 t 标记(联合写法 `T | CDefine`、`T | State` 等): # 它们不是类型本身,取"声明类型"时必须跳过。 _DEFINE_TYPE_MARKER_NAMES: frozenset[str] = frozenset({ 'CDefine', 'State', 'CExport', 'CExtern', 'CStatic', 'CTypedef', @@ -1812,9 +1810,9 @@ _DEFINE_TYPE_MARKER_NAMES: frozenset[str] = frozenset({ def _FirstTypeNameInAnnotation(node: object) -> str | None: - """从注解 AST 中取**第一个真正的类型名**(跳过 t.CDefine/State 等标记)。 + """从注解 AST 中取**第一个真正的类型名**(跳过 CDefine/State 等标记)。 - `DWORD | t.CDefine` → 'DWORD';`HANDLE | t.State` → 'HANDLE'。 + `DWORD | CDefine` → 'DWORD';`HANDLE | State` → 'HANDLE'。 """ if node is None: return None @@ -1836,13 +1834,13 @@ def _FirstTypeNameInAnnotation(node: object) -> str | None: return found return None if isinstance(node, ast.Subscript): - # rawptr[X] / t.CArray[X, N]:指针/聚合,非整数 typedef → 不参与"声明整数类型"判定 + # rawptr[X] / CArray[X, N]:指针/聚合,非整数 typedef → 不参与"声明整数类型"判定 return None return None def DefineDeclIntTypeFromAnnotation(symtab: object, annotation: object) -> tuple[int, bool] | None: - """由 define 的**注解**(`T | t.CDefine`)解析声明整数类型 → (位宽, 是否有符号)。 + """由 define 的**注解**(`T | CDefine`)解析声明整数类型 → (位宽, 是否有符号)。 仅当 T 能经符号表的 typedef 链解析到整数 C 类型时返回;否则 None(指针/聚合/未知)。 供"带类型注册"用:跨模块 define 只能从 .vpi 注解恢复声明类型。 @@ -1866,7 +1864,7 @@ def DefineDeclIntTypeFromAnnotation(symtab: object, annotation: object) -> tuple while base is None and orig is not None and depth < 8: depth += 1 if isinstance(orig, str): - cand: object | None = getattr(t, orig, None) + cand: object | None = getattr(TypeSystem, orig, None) if cand is None: break base = cand @@ -1933,7 +1931,7 @@ def GlobalDeclShadowsDefine(Gen: object, Name: str | None) -> bool: def RequireDefineIntStorable(Value: object, BaseType: object | None, Name: str, AnnotationText: str, Lineno: int, Col: int, FilePath: str, CodeLine: str) -> None: - """t.CDefine 整数常量的可存储性校验(fail-fast;唯一判据,两侧同口径)。 + """CDefine 整数常量的可存储性校验(fail-fast;唯一判据,两侧同口径)。 通过则原样返回(零副作用);不可存储则抛 TypeError,报文含五要素: **文件:行[:列] / 源码片段 / 常量名 / 声明类型或自动推导上限 / 实际值 / @@ -1971,7 +1969,7 @@ def RequireDefineIntStorable(Value: object, BaseType: object | None, Name: str, f'本语言最宽的整数类型为 64 位({DEFINE_STORE_MIN}..{DEFINE_STORE_MAX},' f'覆盖有符号/无符号两种解释),不存在更宽的整数类型 ⇒ 需要扩容。' f'禁止静默截断/降级,已终止编译。可用整数类型: {_DEFINE_INT_TYPE_HINT}。' - f'修法: 把声明类型改为更宽的类型(如 t.CInt64T / uint64);若仍放不下,' + f'修法: 把声明类型改为更宽的类型(如 CInt64T / uint64);若仍放不下,' f'说明该数字超出本语言可表示的整数范围,需要更大的整数类型(扩容);' f'或修正该字面量。位置 {Loc}' + (f',源码: {CodeLine}' if CodeLine else '') @@ -2008,7 +2006,7 @@ def RequireDefineUseWidth(Value: object, ContextWidth: int | None, Name: str, f'(可表示范围: {DefineWidthLoHi(ContextWidth)[0]}..{DefineWidthLoHi(ContextWidth)[1]})。' f'禁止静默截断/降级,已终止编译。' f'修法: 把使用处(变量声明 / 形参 / 运算对象 / 返回注解)的类型加宽到至少 {WMin} 位' - f'(如 t.CInt{WMin}T / CUInt{WMin}T 及更宽类型),或改用更小的常量值。' + f'(如 CInt{WMin}T / CUInt{WMin}T 及更宽类型),或改用更小的常量值。' f'位置 {Loc}' + (f',源码: {CodeLine}' if CodeLine else '') ) @@ -2162,14 +2160,22 @@ def RequireNameDefined(Gen: object, Trans: object, Node: object, Name: str) -> N ) -def IsTModule(module_id: str, symtable: object | None = None) -> bool: - """检查模块标识符是否指向 t 类型模块(支持别名如 import t as tt)""" - if module_id in _T_MODULE_NAMES: - return True - if symtable is not None and hasattr(symtable, 'import_aliases'): - resolved: str = symtable.import_aliases.get(module_id, module_id) - if resolved in _T_MODULE_NAMES: +def AnnotationContainsMarker(node: ast.AST, MarkerName: str) -> bool: + """注解 AST 中是否出现指定内建标记名(裸名,或属性形态的尾名)。""" + if isinstance(node, ast.Name): + return node.id == MarkerName + if isinstance(node, ast.Attribute): + return node.attr == MarkerName + if isinstance(node, ast.BinOp): + return (AnnotationContainsMarker(node.left, MarkerName) + or AnnotationContainsMarker(node.right, MarkerName)) + if isinstance(node, ast.Call): + if AnnotationContainsMarker(node.func, MarkerName): return True + return any(AnnotationContainsMarker(arg, MarkerName) for arg in node.args) + if isinstance(node, ast.Subscript): + return (AnnotationContainsMarker(node.value, MarkerName) + or AnnotationContainsMarker(node.slice, MarkerName)) return False @@ -2177,10 +2183,10 @@ def IsTModule(module_id: str, symtable: object | None = None) -> bool: # virtual / novirtual 修饰符(软关键字)的判据 —— TPC 侧**唯一规则源** # --------------------------------------------------------------------------- # 源码形态 等价既有写法 语义 -# virtual class C: @t.CVTable class C: 类级:强制有 vtable -# novirtual class C: @t.NoVTable class C: 类级:强制无 vtable -# virtual def m(...) @t.CVTable def m(...) 方法级:占 vtable 槽 -# novirtual def m(...) @t.NoVTable def m(...) 方法级:不占 vtable 槽 +# virtual class C: @CVTable class C: 类级:强制有 vtable +# novirtual class C: @NoVTable class C: 类级:强制无 vtable +# virtual def m(...) @CVTable def m(...) 方法级:占 vtable 槽 +# novirtual def m(...) @NoVTable def m(...) 方法级:不占 vtable 槽 # # 解析层(lib/vast/Parser.py:_ParseVirtualModified)只合成同名装饰器,**不新造第二套 # 表示**;语义全部落在既有点位,本节函数是那些点位共用的同一判据(避免多处各写一份 @@ -2192,17 +2198,14 @@ def IsTModule(module_id: str, symtable: object | None = None) -> bool: # 回归性:判据只在"方法带 CVTable/NoVTable 标记"时偏离原行为;全仓既有 .vp 无任何 # 方法级标记(普查结论见报告),故对既有类/既有代码零影响。 def _DecoratorListHasMarker(DecoratorList: object, MarkerName: str) -> bool: - """装饰器表中是否存在指定标记名(接受 @t.X / @X / @t.X() / @X() 四种既有写法)。""" + """装饰器表中是否存在指定内建标记(接受 @X / @X() 两种写法)。""" if not DecoratorList: return False for Dec in DecoratorList: Target: object = Dec if isinstance(Dec, ast.Call): Target = Dec.func - if isinstance(Target, ast.Attribute): - if Target.attr == MarkerName: - return True - elif isinstance(Target, ast.Name): + if isinstance(Target, ast.Name): if Target.id == MarkerName: return True return False @@ -2223,7 +2226,7 @@ def MethodVirtualMarker(MethodNode: ast.AST) -> str | None: def ClassHasFuncLevelCVTable(ClassNode: ast.AST) -> bool: - """类体内是否有方法带方法级 @t.CVTable(对齐 VPC _has_any_func_cvtable)。 + """类体内是否有方法带方法级 @CVTable(对齐 VPC _has_any_func_cvtable)。 跳过构造函数(__new__/__init__/__before_init__)——它们不进虚表。 用于"类的 vtable 是否由方法级标记触发"这一支(类级 NoVTable / 父类 NoVTable / @@ -2260,45 +2263,11 @@ def IsVtableSlotMethod(MethodNode: ast.AST, VtableByClassLevel: bool) -> bool: return bool(VtableByClassLevel) -def IsTModulePath(module_path: str) -> bool: - """检查模块路径是否指向 t 类型模块""" - if module_path in _T_MODULE_NAMES: - return True - if module_path: - t_name: str - for t_name in _T_MODULE_NAMES: - if module_path == t_name or module_path.startswith(t_name + '.'): - return True - return False - - -def AnnotationContainsTType(node: ast.AST, TypeName: str) -> bool: - """检测 AST 节点中是否包含指定名称的 t 模块类型""" - if isinstance(node, ast.Attribute): - if (hasattr(node.value, 'id') and IsTModule(node.value.id) and - node.attr == TypeName): - return True - elif isinstance(node, ast.BinOp): - return AnnotationContainsTType(node.left, TypeName) or AnnotationContainsTType(node.right, TypeName) - elif isinstance(node, ast.Call): - if AnnotationContainsTType(node.func, TypeName): - return True - for arg in node.args: - if AnnotationContainsTType(arg, TypeName): - return True - elif isinstance(node, ast.Subscript): - if AnnotationContainsTType(node.value, TypeName): - return True - if AnnotationContainsTType(node.slice, TypeName): - return True - return False - - -# 内建定长数组构造子的裸名(与 t.CArray 等价的写法): +# 内建定长数组构造子的裸名(与 CArray 等价的写法): # CArray —— from t import * 后的裸名形式 # rawarray —— CArray 的内建复刻名(hashlib 等裸名化重构使用,免写 t. 前缀) # array —— 本轮新增的内建语法保留字(软关键字,仅在类型/注解位置生效, -# 等价 t.CArray[E, N];非类型位置仍可作普通标识符——见 +# 等价 CArray[E, N];非类型位置仍可作普通标识符——见 # Debugger/array-builtin-spec.md 与 FixedArrayKeywordAnnotationError) _FIXED_ARRAY_BARE_NAMES: tuple[str, ...] = ('CArray', 'rawarray', 'array') _ARRAY_KEYWORD: str = 'array' @@ -2310,7 +2279,7 @@ def IsFixedArrayBareName(Name: str) -> bool: def IsListAnnotation(annotation: ast.expr) -> bool: - """检查注解是否为栈上固定数组类型(t.CArray[...] / 内建 array[...]) + """检查注解是否为栈上固定数组类型(CArray[...] / 内建 array[...]) **不含 `list[...]`**:`list` 是 includes/_list.vp 定义的堆上 STL 容器泛型类 (`list[T]` / `list[T, N]` 都走泛型特化),与定长数组无关。 @@ -2318,14 +2287,7 @@ def IsListAnnotation(annotation: ast.expr) -> bool: if not isinstance(annotation, ast.Subscript): return False value = annotation.value - # t.CArray[...] / c.CArray[...] - if (isinstance(value, ast.Attribute) - and isinstance(value.value, ast.Name) - and value.value.id in ('t', 'c') - and value.attr == 'CArray'): - return True - # 裸名 CArray[...](from t import *)/ 内建 rawarray[...] / 内建 array[...]: - # 三者与 t.CArray 等价(array 为本轮新增的内建软关键字,见上方常量注释) + # 裸名 CArray[...] / rawarray[...] / array[...] if (isinstance(value, ast.Name) and value.id in _FIXED_ARRAY_BARE_NAMES): return True @@ -2333,7 +2295,7 @@ def IsListAnnotation(annotation: ast.expr) -> bool: def ExtractListFromBinOp(annotation: ast.expr) -> ast.Subscript | None: - """从 BinOp(BitOr) 注解中提取定长数组部分,如 t.CArray[i32] | t.CPtr""" + """从 BinOp(BitOr) 注解中提取定长数组部分,如 CArray[i32] | CPtr""" if isinstance(annotation, ast.BinOp) and isinstance(annotation.op, ast.BitOr): for side in (annotation.left, annotation.right): if IsListAnnotation(side): @@ -2342,7 +2304,7 @@ def ExtractListFromBinOp(annotation: ast.expr) -> ast.Subscript | None: class ListAnnotationParseResult: - """定长数组注解(t.CArray / rawarray / array)解析结果。 + """定长数组注解(CArray / rawarray / array)解析结果。 is_pointer=True 表示单参数 CArray[type](等价 CArray[type, None])→ 指针模式; is_pointer=False 表示 Tuple(2) 模式 CArray[type, count]。 @@ -2356,10 +2318,10 @@ class ListAnnotationParseResult: def ParseListAnnotation(annotation: ast.expr) -> ListAnnotationParseResult | None: - """解析定长数组注解(t.CArray / rawarray / array),处理 CArray[type, count] / + """解析定长数组注解(CArray / rawarray / array),处理 CArray[type, count] / CArray[type] / BinOp(BitOr) 形式。 - 自动处理 BinOp(BitOr) 包裹(如 CArray[i32, N] | t.CPtr)。 + 自动处理 BinOp(BitOr) 包裹(如 CArray[i32, N] | CPtr)。 返回 None 表示不是定长数组注解(`list[...]` 也返回 None —— 它是堆上 STL 容器)。 """ list_node: ast.expr = annotation @@ -2381,7 +2343,7 @@ def ParseListAnnotation(annotation: ast.expr) -> ListAnnotationParseResult | Non # 内建定长数组构造子 array 的注解校验(唯一规则源) # # array 是**软关键字**:仅在"类型/注解位置"作为内建定长数组构造子生效, -# 语义与 t.CArray 逐点等价(元素类型在前、长度在后)。非类型位置仍是普通 +# 语义与 CArray 逐点等价(元素类型在前、长度在后)。非类型位置仍是普通 # 标识符(如 includes/json 的 def array(...)、numpy 的 def array(...), # 因此**不能**做成词法保留字)。 # @@ -2390,8 +2352,8 @@ def ParseListAnnotation(annotation: ast.expr) -> ListAnnotationParseResult | Non # 各解析入口直接短路(硬内置名)。 # # 新写法要求**恰好两个参数** `array[E, N]`:缺参 / 多参 / 长度非正整型常量 -# 表达式均为 fail-fast(不静默降级)。t.CArray[E] 的单参/长度自动推导写法 -# 仍然可用(t.CArray 不受影响)。 +# 表达式均为 fail-fast(不静默降级)。CArray[E] 的单参/长度自动推导写法 +# 仍然可用(CArray 不受影响)。 # --------------------------------------------------------------------------- def _IsConstExprShape(Node: ast.AST) -> bool: """节点是否为"常量表达式形态"(字面量 / 名字 / 属性 / 常量算术/位运算/一元)。 @@ -2447,7 +2409,7 @@ def FixedArrayKeywordAnnotationError(Annotation: ast.AST, Value = CountNode.value if not (isinstance(Value, int) and not isinstance(Value, bool) and Value > 0): return ("内建定长数组构造子 'array' 的长度必须是正整型常量(>0)" - "——None/0/负数/非整数都不允许(长度自动推导请改用 t.CArray[E])。" + "——None/0/负数/非整数都不允许(长度自动推导请改用 CArray[E])。" "期望形态:array[E, N];正确示例:state: array[uint32, 4]") return None if not _IsConstExprShape(CountNode): @@ -2473,7 +2435,7 @@ def CheckAnnotationHasCInline(annotation_node: ast.AST | None) -> bool: if annotation_node is None: return False if isinstance(annotation_node, ast.Attribute): - if hasattr(annotation_node.value, 'id') and IsTModule(annotation_node.value.id) and annotation_node.attr == 'CInline': + if hasattr(annotation_node.value, 'id') and annotation_node.attr == 'CInline': return True if isinstance(annotation_node, ast.Name): if annotation_node.id == 'CInline': @@ -2554,7 +2516,7 @@ def FindStructNameInAnnotationWithContext(Node: ast.AST, Trans: object, Gen: obj Names: dict | set = StructNames if StructNames is not None else Gen.structs return FindStructNameInAnnotation( Node, Names, - TCAliasMap=getattr(Trans, '_t_c_imported_names', {}), + TCAliasMap=getattr(Trans, '_from_import_aliases', {}), StructSha1Map=getattr(Gen, '_struct_sha1_map', {})) @@ -2573,17 +2535,14 @@ def AnnotationContainsName(annotation: ast.AST, name: str) -> bool: def IsCPtrNode(node: ast.AST) -> bool: - """检查节点是否为 t.CPtr 属性引用。""" - return (isinstance(node, ast.Attribute) - and isinstance(node.value, ast.Name) - and node.value.id == 't' - and node.attr == 'CPtr') + """检查节点是否为 CPtr 标记(裸名 `CPtr`)。""" + return isinstance(node, ast.Name) and node.id == 'CPtr' # 值引用参数标记名 → 自动取址模式(仅注解 AST 内按名字识别,非真实类): # 'CRef' → 'ref' (&T :实参非指针左值取址,右值 fail-fast) # 'CTempRef' → 'temp' (&temp T :实参非指针时在调用方建同型临时再取址) -# 'CAutoPtr' → 'always' (t.CAutoPtr:无条件取址,保持既有语义) +# 'CAutoPtr' → 'always' (CAutoPtr:无条件取址,保持既有语义) _AUTO_ADDR_MARKER_MODES: dict[str, str] = { 'CRef': 'ref', 'CTempRef': 'temp', 'CAutoPtr': 'always', } @@ -2593,7 +2552,7 @@ def FindAutoAddrMode(node: ast.AST | None) -> str | None: """注解 AST 内查找自动取址模式标记,返回 'ref' / 'temp' / 'always';无则 None。 只按名字识别(Attribute.attr 或 Name.id),递归联合/嵌套注解;CRef/CTempRef - 非真实类,不出现在 lib/includes/t.py。 + 非真实类,不出现在类型模型模块中。 """ if node is None: return None @@ -2613,12 +2572,12 @@ def FindAutoAddrMode(node: ast.AST | None) -> str | None: def IsCPtrSubscriptNode(node: ast.AST) -> bool: - """检查节点是否为 t.CPtr[T] 下标指针类型(非裸标记,裸标记见 IsCPtrNode)。 + """检查节点是否为 CPtr[T] 下标指针类型(非裸标记,裸标记见 IsCPtrNode)。 与 VPC TypeGenResolve._is_cptr_subscript(TypeGenResolve.vp:1485-1505)同口径: - value 必须是 t.CPtr 属性引用(只认 t 前缀,c.CPtr[...] 不认); - 切片内的指针层级不限(t.CPtr[t.CPtr]、t.CPtr[t.CPtr[t.CInt]] 均命中)。 - 链式写法 t.CPtr[T][T](value 是 Subscript)两套编译器均不认作该标记。 + value 必须是 CPtr 属性引用(只认 t 前缀,CPtr[...] 不认); + 切片内的指针层级不限(CPtr[CPtr]、CPtr[CPtr[CInt]] 均命中)。 + 链式写法 CPtr[T][T](value 是 Subscript)两套编译器均不认作该标记。 """ return (isinstance(node, ast.Subscript) and IsCPtrNode(node.value)) @@ -2626,35 +2585,25 @@ def IsCPtrSubscriptNode(node: ast.AST) -> bool: # 指针下标的 base 名:rawptr 是编译器内置语法(TPC/VPC 双端保留字,见 # includes/builtins.vp 语义注释与 TypeAnnotationResolver._BUILTIN_ROWPTR_NAME), -# 单独 rawptr 等价 t.CPtr(void*)。 +# 单独 rawptr 等价 CPtr(void*)。 _RAWPTR_SUBSCRIPT_NAME: str = 'rawptr' -# 指针标记类型名(t.CPtr):裸名书写 `CPtr[T]` / 导入别名 `X`(from t import CPtr as X) +# 指针标记类型名(CPtr):裸名书写 `CPtr[T]` / 导入别名 `X`(from t import CPtr as X) # 都归一到本名。 _CPTR_TYPE_NAME: str = 'CPtr' def ResolveTCImportAliasName(NameId: str, symtable: object | None = None, TCAliasMap: dict[str, tuple[str, str]] | None = None) -> str: - """t/c 导入别名 → 原始类型名('X' → 'CPtr'、'myint' → 'CInt');未命中原样返回。 - - 两张同源别名表(注册点唯一:HandlesImports._EmitImportFromDeclarationsLlvm / - _RegisterFromImportAliases,与 SymbolTable 序列化),调用方按手头有的表注入: - - TCAliasMap:{别名: (模块, 原名)}(Trans._t_c_imported_names / - DeclarationGenerator._t_c_imported_names 同结构) - - symtable._t_type_symbols:{别名: t.CType 子类}(from t import CPtr as X → t.CPtr) - 非 t/c 模块的 from 导入别名(from ast import AST as A)不参与归一。 - """ + """from-import 别名 → 原始类型名('X' → 'CPtr'、'myint' → 'CInt');未命中原样返回。""" if not NameId: return NameId if TCAliasMap: Entry: tuple[str, str] | None = TCAliasMap.get(NameId) if Entry: - SrcModule, SrcName = Entry - if IsTModule(SrcModule): - return SrcName + return Entry[1] if symtable is not None: - Cls: object | None = getattr(symtable, '_t_type_symbols', {}).get(NameId) + Cls: object | None = getattr(symtable, '_builtin_type_symbols', {}).get(NameId) if Cls is not None: return getattr(Cls, '__name__', NameId) return NameId @@ -2663,10 +2612,10 @@ def ResolveTCImportAliasName(NameId: str, symtable: object | None = None, def IsRawPtrSubscriptNode(node: ast.AST) -> bool: """检查节点是否为内置裸指针下标 `rawptr[T]`(非裸标记 rawptr)。 - `rawptr[T]` 语义 = `t.CPtr[T]` = 源码联合写法 `T | t.CPtr`(Ptr(T)),三者 + `rawptr[T]` 语义 = `CPtr[T]` = 源码联合写法 `T | CPtr`(Ptr(T)),三者 必须走同一解析与拼名路径,否则同一类型的不同书写会分裂出不同特化名 (结构体/方法声明/调用点三处不一致)。 - 注意:本判据**只**认 `rawptr[T]`;`t.CPtr[T]` / 裸名 `CPtr[T]` 由 + 注意:本判据**只**认 `rawptr[T]`;`CPtr[T]` / 裸名 `CPtr[T]` 由 IsPtrSubscriptNode 判定(见下),二者共用同一条脱糖规则 (DesugarPtrSubscriptToUnion),此处保持 rawptr 专用以便仍需区分书写时使用。 """ @@ -2676,7 +2625,7 @@ def IsRawPtrSubscriptNode(node: ast.AST) -> bool: def IsI8DoublePtrType(T: object) -> bool: - """是否为 **i8 系两层指针**(`i8**`)—— 即 `T | t.CPtr` 在 T 的类型丢失后**退化**成的形状。 + """是否为 **i8 系两层指针**(`i8**`)—— 即 `T | CPtr` 在 T 的类型丢失后**退化**成的形状。 与 "T 是有类型的上层指针" 无关:只认 `i8**`(`Ptr(Ptr(i8))`)。用于识别 「类引用指针被解析成通用两层指针」这类**类型信息丢失**。 @@ -2689,11 +2638,11 @@ def IsI8DoublePtrType(T: object) -> bool: def IsClassRefPtrAnnotation(Ann: ast.AST, symtable: object | None = None) -> bool: - """注解是否为「**指针包装的类引用**」:`rawptr[Mod.Class]` / `Mod.Class | t.CPtr`。 + """注解是否为「**指针包装的类引用**」:`rawptr[Mod.Class]` / `Mod.Class | CPtr`。 只回答"这个注解**本应**解析出结构体指针",不做任何类型解析,判据保守: - - 必须是指针包装:`rawptr[T]` / `t.CPtr[T]` / 裸名 `CPtr[T]`,或含 `t.CPtr` - 标记的联合写法 `T | t.CPtr`; + - 必须是指针包装:`rawptr[T]` / `CPtr[T]` / 裸名 `CPtr[T]`,或含 `CPtr` + 标记的联合写法 `T | CPtr`; - 内层须是类引用形态:`Attribute` 且**根模块不是 `t` / `c`** (如 `ExprGenFstr.ExprGenFstr`、`llvmlite.LLVMType`),或首字母大写的裸名 (类名书写惯例)。 @@ -2717,7 +2666,7 @@ def IsClassRefPtrAnnotation(Ann: ast.AST, symtable: object | None = None) -> boo while isinstance(Cur, ast.Attribute): Cur = Cur.value Root: str = Cur.id if isinstance(Cur, ast.Name) else '' - return Root not in ('t', 'c') + return bool(Root) if isinstance(Inner, ast.Name): return bool(Inner.id) and Inner.id[0].isupper() return False @@ -2725,10 +2674,10 @@ def IsClassRefPtrAnnotation(Ann: ast.AST, symtable: object | None = None) -> boo def IsPtrSubscriptNode(node: ast.AST, symtable: object | None = None, TCAliasMap: dict[str, tuple[str, str]] | None = None) -> bool: - """检查节点是否为"指针下标类型":`rawptr[T]` / `t.CPtr[T]` / 裸名 `CPtr[T]` + """检查节点是否为"指针下标类型":`rawptr[T]` / `CPtr[T]` / 裸名 `CPtr[T]` / 导入别名 `X[T]`(`from t import CPtr as X`)。 - 三者语义完全相同(= 源码联合写法 `T | t.CPtr` = Ptr(T),见 + 三者语义完全相同(= 源码联合写法 `T | CPtr` = Ptr(T),见 builtins.vp 与 t.py 的 CPtr 语义注释):内层 T 按**参数注解 `a: T` 的规则** 解析(跨模块类 → '.X'),再包一层指针——T 为类引用时该层被结构体 自身吸收('.X*'),其余(标量 / 已是指针的 typedef / 泛型容器特化 / @@ -2739,9 +2688,9 @@ def IsPtrSubscriptNode(node: ast.AST, symtable: object | None = None, Attribute 'CPtr' 与 Name 'CPtr' 两种书写)。 - 传入 symtable 时,`import t as tt` 的 `tt.CPtr[T]` 一并命中(与声明端 "只看 attr 名"的 ValueIsCPtr 判据对齐,避免同一书写两端分裂); - 不传(名称域 ResolveTypeArgStr 的字面名场景)时只认字面 't'。 + 字面名场景直接按内建名归一。 - 导入名别名(`from t import CPtr as X` 的 `X[T]`)经别名表解析 X→CPtr - (TCAliasMap 或 symtable._t_type_symbols,见 ResolveTCImportAliasName), + (TCAliasMap 或 symtable._builtin_type_symbols,见 ResolveTCImportAliasName), 定义端与声明端各自注入手头的同一批表,判据只有这一处。 """ if IsRawPtrSubscriptNode(node): @@ -2756,28 +2705,27 @@ def IsPtrSubscriptNode(node: ast.AST, symtable: object | None = None, def DesugarPtrSubscriptToUnion(node: ast.AST, symtable: object | None = None, TCAliasMap: dict[str, tuple[str, str]] | None = None) -> ast.AST: - """把指针下标(`rawptr[T]` / `t.CPtr[T]` / 裸名 `CPtr[T]` / 别名 `X[T]`) - 折叠成等价的联合写法 `T | t.CPtr`。 + """把指针下标(`rawptr[T]` / `CPtr[T]` / 裸名 `CPtr[T]` / 别名 `X[T]`) + 折叠成等价的联合写法 `T | CPtr`。 - 内层 T 递归折叠(`rawptr[rawptr[X]]` → `(X | t.CPtr) | t.CPtr`、 - `t.CPtr[rawptr[X]]` → `(X | t.CPtr) | t.CPtr`), + 内层 T 递归折叠(`rawptr[rawptr[X]]` → `(X | CPtr) | CPtr`、 + `CPtr[rawptr[X]]` → `(X | CPtr) | CPtr`), 与 VPC TypeGenResolve.resolve_annotation_type 的 Subscript 分支同语义 (T → Ptr(T),层数逐层外包);折叠后交给 HandlesTypeMerge 既有的 - 联合解析(_CollectAllOperandTypes 会把嵌套 BitOr 拉平成 [T, t.CPtr, ...], + 联合解析(_CollectAllOperandTypes 会把嵌套 BitOr 拉平成 [T, CPtr, ...], struct 基类型吸收一层、其余逐层累加),从而: - 内层 T 走通用类型解析(含跨模块类经 Gen.structs 反查 SHA1 前缀); - - `rawptr[X]` / `t.CPtr[X]` / `X[T]` / `X | t.CPtr` 得到同一 CTypeInfo + - `rawptr[X]` / `CPtr[X]` / `X[T]` / `X | CPtr` 得到同一 CTypeInfo (PtrCount/BaseType 一致)与同一泛型实参串(逐层 '*')。 非指针下标节点原样返回(调用方无需先判类型);symtable/TCAliasMap 透传给 判据(识别 `import t as tt` 的 `tt.CPtr[T]` 与 `from t import CPtr as X` 的 - `X[T]` 内层嵌套)。折叠产物统一用字面 `t.CPtr` 标记,与源码联合写法同形。 + `X[T]` 内层嵌套)。折叠产物统一用字面 `CPtr` 标记,与源码联合写法同形。 """ if not IsPtrSubscriptNode(node, symtable, TCAliasMap): return node inner: ast.AST = DesugarPtrSubscriptToUnion(node.slice, symtable, TCAliasMap) - cptr_marker: ast.AST = ast.Attribute( - value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load()) + cptr_marker: ast.AST = ast.Name(id='CPtr', ctx=ast.Load()) union_node: ast.AST = ast.BinOp(left=inner, op=ast.BitOr(), right=cptr_marker) try: ast.copy_location(union_node, node) @@ -2844,12 +2792,10 @@ def GenericArgRawName(NameId: str) -> str: def MangleTypeArgByRegistry(ArgStr: str) -> str: """实参串 → 最终 mangled 实参(HandlesClassDef._mangle_generic_class_name 的单项逻辑,逐分支同构):t 类型名经 NameToLLVM 归一(CInt32T → 'i32', - 't.CInt'/'c.CInt' 先去模块前缀再归一),浮点按 Size 归一为 f{n} + 'CInt'/'CInt' 先去模块前缀再归一),浮点按 Size 归一为 f{n} (CDouble → 'f8'),未注册名原样保留(含指针层数与已解析的内层名)。 """ LookupStr: str = ArgStr - if ArgStr.startswith('t.') or ArgStr.startswith('c.'): - LookupStr = ArgStr[2:] LlvmStr: str | None = CTypeRegistry.NameToLLVM(LookupStr) if not LlvmStr: return ArgStr @@ -2868,7 +2814,7 @@ def AddPointerLayers(TypeStr: str, Layers: int) -> str: """给已解析的类型串追加 Layers 层指针(空/void/void* 的首层归一化为 i8*)。 与 LLVMTypeMapper._add_pointer_level 同口径;名称域与类型域因此对 - rawptr[t.CVoid] 一致地给出 i8*(唯一允许的 void 兜底)。 + rawptr[CVoid] 一致地给出 i8*(唯一允许的 void 兜底)。 """ Result: str = TypeStr for _ in range(Layers): @@ -2881,13 +2827,13 @@ def AddPointerLayers(TypeStr: str, Layers: int) -> str: def IsCPtrMarkerNode(Node: ast.AST, symtable: object | None = None, TCAliasMap: dict[str, tuple[str, str]] | None = None) -> bool: - """`t.CPtr` 裸指针标记(含 `import t as tt` 与 `from t import CPtr as X` 别名): + """`CPtr` 裸指针标记(含 `import t as tt` 与 `from t import CPtr as X` 别名): 联合写法里贡献一层 '*'。 与 IsCPtrNode 的区别:仅按 attr 名 + t 模块前缀判定,不看切片 - (`t.CPtr[T]` 下标是**基类型**而非层数标记,见 ResolveTypeArgStr 的 + (`CPtr[T]` 下标是**基类型**而非层数标记,见 ResolveTypeArgStr 的 Subscript 分支)。 - - Attribute:`t.CPtr` / `tt.CPtr`(t 模块别名经 symtable.import_aliases 解析)。 + - Attribute:`CPtr` / `tt.CPtr`(t 模块别名经 symtable.import_aliases 解析)。 - Name:经别名表归一为 'CPtr' 的书写名(`from t import CPtr as X` 的 `X`); 字面裸名 `CPtr` 是否算标记取决于该模块是否 `from t import CPtr` (别名表命中一致:两端都由同一批表判定,不另设白名单)。 @@ -2895,14 +2841,14 @@ def IsCPtrMarkerNode(Node: ast.AST, symtable: object | None = None, if isinstance(Node, ast.Attribute): return (Node.attr == _CPTR_TYPE_NAME and isinstance(Node.value, ast.Name) - and IsTModule(Node.value.id, symtable)) + ) if isinstance(Node, ast.Name): return ResolveTCImportAliasName(Node.id, symtable, TCAliasMap) == _CPTR_TYPE_NAME return False def FlattenUnionOperands(Node: ast.AST) -> list[ast.AST]: - """拉平嵌套 BitOr,按书写顺序返回操作数(`A | t.CPtr | t.CPtr` → [A, CPtr, CPtr])。""" + """拉平嵌套 BitOr,按书写顺序返回操作数(`A | CPtr | CPtr` → [A, CPtr, CPtr])。""" if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr): return FlattenUnionOperands(Node.left) + FlattenUnionOperands(Node.right) return [Node] @@ -2917,34 +2863,30 @@ def ResolveTypeArgStr(Node: ast.AST, TCAliasMap: dict[str, tuple[str, str]] | No (与参数注解的 %"{sha1}.X" 同前缀);其余按 NormalizeGenericArgName 归一('int'/'i32'/'str' 原名、'char'/'bool' → 'i8'、C 整数/浮点族 → 'int'/'double') - - ast.Attribute: t 模块类型按 CTypeRegistry.NameToLLVM 解析(t.CPtr → i8*、 - t.CInt → i32);跨模块类引用 module.X → '{sha1}.X';其余 '{mod}.{attr}' - - ast.Subscript: 指针下标(`rawptr[T]` / `t.CPtr[T]` / 裸名 `CPtr[T]` / + - ast.Attribute: t 模块类型按 CTypeRegistry.NameToLLVM 解析(CPtr → i8*、 + CInt → i32);跨模块类引用 module.X → '{sha1}.X';其余 '{mod}.{attr}' + - ast.Subscript: 指针下标(`rawptr[T]` / `CPtr[T]` / 裸名 `CPtr[T]` / 导入别名 `X[T]`)已在入口脱糖为上面的联合写法(走同一规则),故此处只剩泛型容器: '<容器名>[<已解析实参>]'(多实参 '][' 分隔),容器名的 模块前缀由调用方(_mangle_name / '%"{模sha1}.{特化名}"')统一加 - ast.BinOp(BitOr)(含指针下标脱糖而来): 取非 CPtr 侧为基类型, - 每个 `t.CPtr` 标记追加一层 '*'(`X | t.CPtr` ≡ `rawptr[X]` ≡ - `t.CPtr[X]` → '.X*';`rawptr[rawptr[X]]` → '.X**'; - 标量 `int | t.CPtr` → 'int*') + 每个 `CPtr` 标记追加一层 '*'(`X | CPtr` ≡ `rawptr[X]` ≡ + `CPtr[X]` → '.X*';`rawptr[rawptr[X]]` → '.X**'; + 标量 `int | CPtr` → 'int*') - 其余形态: ast.unparse 注意:名称域**不做**"裸类引用吸收一层 CPtr"(那是注解→LLVM 类型域的规则, 见 DeclarationGenerator._is_bare_class_ref_annotation):名称域描述的是类型 身份('X' = X 本身、'X*' = 指向 X 的指针),逐层累加,否则 - `rawptr[X]` 与 `X | t.CPtr` 会分裂成两个名字。 + `rawptr[X]` 与 `X | CPtr` 会分裂成两个名字。 """ if IsPtrSubscriptNode(Node, TCAliasMap=TCAliasMap): Node = DesugarPtrSubscriptToUnion(Node, TCAliasMap=TCAliasMap) if isinstance(Node, ast.Name): tn: str = Node.id if TCAliasMap and tn in TCAliasMap: - # t 模块别名(from t import CInt as myint)按内建归一表解析到同一名字 - # ('myint' 与 'CInt' 都 → 'int'),避免同义写法分裂特化名 SrcModule, SrcName = TCAliasMap[tn] - if IsTModule(SrcModule): - return NormalizeGenericArgName(SrcName) - return f'{SrcModule}.{SrcName}' + return NormalizeGenericArgName(SrcName) if StructSha1Map and tn in StructSha1Map: return f'{StructSha1Map[tn]}.{tn}' return NormalizeGenericArgName(tn) @@ -2959,12 +2901,12 @@ def ResolveTypeArgStr(Node: ast.AST, TCAliasMap: dict[str, tuple[str, str]] | No def _ResolveAttributeArgStr(Node: ast.Attribute, TCAliasMap: dict[str, tuple[str, str]] | None, StructSha1Map: dict[str, str] | None) -> str: - """Attribute 形态(t.CInt / ast.AST / .AST)→ 实参串。""" + """Attribute 形态(CInt / ast.AST / .AST)→ 实参串。""" if not isinstance(Node.value, ast.Name): return ast.unparse(Node) ModName: str = Node.value.id AttrName: str = Node.attr - if IsTModule(ModName) or (TCAliasMap and ModName in TCAliasMap): + if TCAliasMap and ModName in TCAliasMap: LlvmStr: str | None = CTypeRegistry.NameToLLVM(AttrName) if LlvmStr is not None: return LlvmStr @@ -2977,7 +2919,7 @@ def _ResolveAttributeArgStr(Node: ast.Attribute, TCAliasMap: dict[str, tuple[str def _ResolveSubscriptArgStr(Node: ast.Subscript, TCAliasMap: dict[str, tuple[str, str]] | None, StructSha1Map: dict[str, str] | None) -> str: - """下标形态(t.CPtr[T] / 泛型容器 list[X] / dict[K,V])→ 实参串。 + """下标形态(CPtr[T] / 泛型容器 list[X] / dict[K,V])→ 实参串。 容器名('list' / 'dict' ...)**不带**模块前缀:它只是 _mangle_generic_class_name 的基名,特化名的模块前缀由调用方统一加(定义端 _mangle_name / 声明端 @@ -3002,7 +2944,7 @@ def _ResolveSubscriptArgStr(Node: ast.Subscript, TCAliasMap: dict[str, tuple[str def _ResolveUnionArgStr(Node: ast.BinOp, TCAliasMap: dict[str, tuple[str, str]] | None, StructSha1Map: dict[str, str] | None) -> str: - """联合形态(X | t.CPtr | ...)实参串:非 CPtr 侧为基类型,CPtr 标记逐层加 '*'。 + """联合形态(X | CPtr | ...)实参串:非 CPtr 侧为基类型,CPtr 标记逐层加 '*'。 标记判据是同一处 IsCPtrMarkerNode(含 `from t import CPtr as X` 的裸标记别名), 别名经 TCAliasMap 解析;没带别名表的 `import t as tt` 的 `tt.CPtr` 在此域 @@ -3016,7 +2958,7 @@ def _ResolveUnionArgStr(Node: ast.BinOp, TCAliasMap: dict[str, tuple[str, str]] elif not BaseType: BaseType = ResolveTypeArgStr(Operand, TCAliasMap, StructSha1Map) if not BaseType: - # 只有 CPtr 标记(如 `t.CPtr | t.CPtr`):等价 void* 逐层——首层 i8* + # 只有 CPtr 标记(如 `CPtr | CPtr`):等价 void* 逐层——首层 i8* return AddPointerLayers('void', Layers) return AddPointerLayers(BaseType, Layers) @@ -3031,7 +2973,7 @@ def GetStructSha1MapFromSymtab(Symtab: object | None) -> dict[str, str]: def GetTCAliasMapFromSymtab(Symtab: object | None) -> dict | None: """从符号表取 t/c 导入别名表(`from t import CInt as myint`)。缺则 None。""" _Tr: Any = getattr(Symtab, 'translator', None) - _Map: Any = getattr(_Tr, '_t_c_imported_names', None) if _Tr is not None else None + _Map: Any = getattr(_Tr, '_from_import_aliases', None) if _Tr is not None else None return _Map if isinstance(_Map, dict) and _Map else None @@ -3044,7 +2986,7 @@ def IsGenericClassSubscriptBase(Node: ast.AST, Symtab: object | None = None, 就是类(实测符号表 `list` 条目 IsStruct=True),故本判据等价覆盖声明端的 `non_struct_types ∪ _generic_class_names`;用户泛型类(Box[T])同样命中。 - 只认 Name 形态:`t.CPtr[...]` / `t.CArray[...]` / 裸 `array[...]` / + 只认 Name 形态:`CPtr[...]` / `CArray[...]` / 裸 `array[...]` / `rawptr[...]` 等由调用方各自分支先行处理,不走这里。 """ if not isinstance(Node, ast.Name) or not Node.id: @@ -3083,10 +3025,10 @@ def ResolveGenericClassSpecName(Node: ast.Subscript, Symtab: object | None = Non 既有分支处理(调用点必须放在那些分支**之后**)。 必要性:单参泛型下标此前在两个注解解析器里都 miss(TypeAnnotationResolver 只认 - 双参定长 t.CArray[T, N];LLVMTypeMapper 亦然)⇒ 落到"未知类型"兜底 i32 / 空 CTypeInfo, + 双参定长 CArray[T, N];LLVMTypeMapper 亦然)⇒ 落到"未知类型"兜底 i32 / 空 CTypeInfo, 形参与成员类型整体错位(现场:ClassGenGeneric._specialize_generic_class 的 形参 `type_args: list[str]*` 在符号表里成 i32;字段 - `TypeGenBase.CTypedefNames: list[str] | t.CPtr` 成 i8*)。 + `TypeGenBase.CTypedefNames: list[str] | CPtr` 成 i8*)。 """ if not isinstance(Node, ast.Subscript): return None @@ -3114,7 +3056,7 @@ def ResolveGenericTypeArgStr(Node: ast.AST, TCAliasMap: dict[str, tuple[str, str ('int' → 'int'、'i32' → 'i32'、'str' → 'str'、'CInt32T' → 'int'、 'CFloat64T' → 'double'、'CChar' → 'i8') - 其余形态(Attribute / Subscript(含 rawptr[...])/ BinOp / 混合 Tuple 元素): - ResolveTypeArgStr(rawptr[T] 脱糖 → 逐层 '*'、t.CPtr → 'i8*'、跨模块类 → sha1 前缀) + ResolveTypeArgStr(rawptr[T] 脱糖 → 逐层 '*'、CPtr → 'i8*'、跨模块类 → sha1 前缀) → MangleTypeArgByRegistry """ return MangleTypeArgByRegistry(ResolveTypeArgStr(Node, TCAliasMap, StructSha1Map)) diff --git a/lib/core/Translator/AnnotationLoader.py b/lib/core/Translator/AnnotationLoader.py index 54d8c4f..33345c2 100644 --- a/lib/core/Translator/AnnotationLoader.py +++ b/lib/core/Translator/AnnotationLoader.py @@ -6,12 +6,12 @@ import importlib import types from typing import Any -import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib/includes) +import lib._bootstrap # noqa: F401 设置 sys.path(项目根 + lib) from lib.core.Handles.HandlesBase import CTypeInfo -from lib.core.SymbolUtils import IsTModule, AnnotationContainsName, ExpandSoftKeywords -from lib.includes import t -from lib.includes.t import CType, CEnum +from lib.core.SymbolUtils import AnnotationContainsName, ExpandSoftKeywords +from lib.core import TypeSystem +from lib.core.TypeSystem import CType, CEnum from lib.constants.config import mode as _config_mode from lib.core.VLogger import get_logger as _vlog @@ -47,7 +47,7 @@ class AnnotationLoaderMixin: # 注册枚举类型 EnumNode: CTypeInfo = CTypeInfo() EnumNode.Name = AttrName - EnumNode.BaseType = t.CEnum() + EnumNode.BaseType = TypeSystem.CEnum() EnumNode.IsEnum = True EnumNode.set('enum_class', attr) EnumNode.set('source', 'annotation_module') @@ -71,7 +71,7 @@ class AnnotationLoaderMixin: if isinstance(member, int): MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = MemberName - MemberNode.BaseType = t.CEnum(AttrName) + MemberNode.BaseType = TypeSystem.CEnum(AttrName) MemberNode.value = member MemberNode.EnumName = AttrName MemberNode.library_name = lib_name @@ -230,10 +230,10 @@ class AnnotationLoaderMixin: self.SymbolTable.insert(FullName, TypeInfo) count += 1 - # 再次遍历 AST,查找注解文件中的 typedef 语句(AnnAssign with t.CTypedef) + # 再次遍历 AST,查找注解文件中的 typedef 语句(AnnAssign with CTypedef) # 注意:必须在类定义处理完之后再处理 typedef typedef_annots: list[tuple[str, str]] = [] - # 查找 CEnum 成员变量(AnnAssign with t.CEnum | t.State 或 t.CEnum) + # 查找 CEnum 成员变量(AnnAssign with CEnum | State 或 CEnum) cEnumMembers: list[tuple[str, int | None]] = [] try: with open(ModuleName, 'r', encoding='utf-8') as f: @@ -241,7 +241,7 @@ class AnnotationLoaderMixin: ann_content = ExpandSoftKeywords(ann_content) ann_tree: ast.Module = ast.parse(ann_content, ModuleName) for node in ann_tree.body: - # 检测 xxx: t.CEnum 形式的枚举成员变量 + # 检测 xxx: CEnum 形式的枚举成员变量 if isinstance(node, ast.AnnAssign): if isinstance(node.target, ast.Name) and node.annotation: TargetName: str = node.target.id @@ -252,8 +252,8 @@ class AnnotationLoaderMixin: if AnnotationContainsName(node.annotation, 'CEnum'): IsCenum = True elif isinstance(node.annotation, ast.Attribute): - # 直接是 t.CEnum - if node.annotation.attr == t.CEnum.__name__: + # 直接是 CEnum + if node.annotation.attr == TypeSystem.CEnum.__name__: IsCenum = True if IsCenum: @@ -273,7 +273,7 @@ class AnnotationLoaderMixin: # 注册枚举成员 MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = TargetName - MemberNode.BaseType = t.CEnum(TypePrefix) + MemberNode.BaseType = TypeSystem.CEnum(TypePrefix) MemberNode.value = value MemberNode.EnumName = TypePrefix MemberNode.library_name = TypePrefix @@ -288,14 +288,14 @@ class AnnotationLoaderMixin: ann_content = ExpandSoftKeywords(ann_content) ann_tree: ast.Module = ast.parse(ann_content, ModuleName) for node in ann_tree.body: - # 检测 xxx: t.CTypedef = xxx 形式的 typedef 语句 + # 检测 xxx: CTypedef = xxx 形式的 typedef 语句 if isinstance(node, ast.AnnAssign): if isinstance(node.target, ast.Name) and node.annotation and node.value: TargetName: str = node.target.id - # 检查注解是否是 t.CTypedef + # 检查注解是否是 CTypedef if isinstance(node.annotation, ast.Attribute): if isinstance(node.annotation.value, ast.Name): - if IsTModule(node.annotation.value.id) and node.annotation.attr == 'CTypedef': + if node.annotation.attr == 'CTypedef': # 检查值是否是 Name if isinstance(node.value, ast.Name): original_name: str = node.value.id diff --git a/lib/core/Translator/BaseTranslator.py b/lib/core/Translator/BaseTranslator.py index 8197c54..9d35f52 100644 --- a/lib/core/Translator/BaseTranslator.py +++ b/lib/core/Translator/BaseTranslator.py @@ -75,15 +75,15 @@ class BaseTranslatorMixin: # 以下属性原先在外部懒注入,此处显式初始化以避免 hasattr/getattr 动态反射 self.config: Any = None self._ImportedModules: set[str] | None = None - self._t_c_imported_names: dict = {} - # 调用点热点统计(--hotspot-sites):None=未启用(零影响),否则为调用点计数落盘文件路径 - self.HotspotSitesFile: str | None = None - # 是否对全部直接 call 点插桩(忽略白名单;体积/开销大) - self.HotspotSitesAll: bool = False - # 白名单被调函数基名列表;None=使用默认内存/字符串族白名单 - self.HotspotCallees: list[str] | None = None - # 注册策略:False=种子 CLI 单模块(在 main 入口注册);True=Projectrans - # 多模块(每模块 @llvm.global_ctors 自注册,见 BaseGen._InstallHotspotSitesModuleLocal) + self._from_import_aliases: dict = {} + # 调用点热点统计(--hotspot-sites):None=未启用(零影响),否则为调用点计数落盘文件路径 + self.HotspotSitesFile: str | None = None + # 是否对全部直接 call 点插桩(忽略白名单;体积/开销大) + self.HotspotSitesAll: bool = False + # 白名单被调函数基名列表;None=使用默认内存/字符串族白名单 + self.HotspotCallees: list[str] | None = None + # 注册策略:False=种子 CLI 单模块(在 main 入口注册);True=Projectrans + # 多模块(每模块 @llvm.global_ctors 自注册,见 BaseGen._InstallHotspotSitesModuleLocal) self.HotspotSitesModuleLocal: bool = False # 函数级 DWARF 调试元数据(--dwarf / --asan 自动开启):False=未启用 # (零影响),True=生成的 .ll 携带每函数 !dbg(见 LlvmGenerator.GenerateCCode) diff --git a/lib/core/Translator/ConstEval.py b/lib/core/Translator/ConstEval.py index 2c86d04..3229532 100644 --- a/lib/core/Translator/ConstEval.py +++ b/lib/core/Translator/ConstEval.py @@ -123,8 +123,8 @@ class ConstEvalMixin: if byte_order == 'big' and isinstance(ElemType, ir.IntType) and ElemType.width in (16, 32, 64): swapped: list[ir.Constant] = [] for c in constants: - if isinstance(c, ir.Constant) and isinstance(c.type, ir.IntType) and isinstance(c.constant, int): - swapped_val: int = self._bswap_constant_value(int(c.constant), ElemType.width) + if isinstance(c, ir.Constant) and isinstance(type, ir.IntType) and isinstance(constant, int): + swapped_val: int = self._bswap_constant_value(int(constant), ElemType.width) swapped.append(ir.Constant(ElemType, swapped_val)) else: swapped.append(c) diff --git a/lib/core/Translator/LlvmGenerator.py b/lib/core/Translator/LlvmGenerator.py index 9260423..4b4359d 100644 --- a/lib/core/Translator/LlvmGenerator.py +++ b/lib/core/Translator/LlvmGenerator.py @@ -7,12 +7,12 @@ import llvmlite.ir as ir from lib.core.LlvmCodeGenerator import LlvmCodeGenerator from lib.core.Handles.HandlesBase import CTypeInfo from lib.core.Handles.HandlesBase import CTypeInfo as _CTypeInfo, CTypeHelper -from lib.includes import t +from lib.core import TypeSystem from lib.constants.config import mode as _config_mode from lib.core.VLogger import get_logger as _vlog from lib.core.DecoratorPass import run as _run_decorator_pass from lib.core.SymbolUtils import ( - IsTModule, AnnotationContainsName, RequireDefineConstStorable, + AnnotationContainsName, RequireDefineConstStorable, DefineIntWidthOf, DefineIntSignednessOf, ) # 治本修复:导入 ConstEvaluator 用于预扫描 CDefine 常量的复杂表达式求值 @@ -50,16 +50,12 @@ class LlvmGeneratorMixin: elif hasattr(base, 'attr'): bases.append(base.attr) has_methods: bool = any(isinstance(item, ast.FunctionDef) for item in Node.body) - # 检测 @t.NoVTable 装饰器(非多态继承基类标记) + # 检测 @NoVTable 装饰器(非多态继承基类标记) has_novtable: bool = False if hasattr(Node, 'decorator_list') and Node.decorator_list: for decorator in Node.decorator_list: - if isinstance(decorator, ast.Attribute): - if getattr(decorator.value, 'id', None) == 't' and decorator.attr == 'NoVTable': - has_novtable = True - elif isinstance(decorator, ast.Name): - if decorator.id == 'NoVTable': - has_novtable = True + if isinstance(decorator, ast.Name) and decorator.id == 'NoVTable': + has_novtable = True Gen._class_graph[Node.name] = { 'bases': bases, 'has_methods': has_methods, @@ -78,7 +74,7 @@ class LlvmGeneratorMixin: def _extract_const_value(node: ast.AST) -> int | str | float | None: """求值 CDefine 常量表达式,支持 Constant、BinOp、UnaryOp、Name(引用其他 define)、Call(类型构造)。 - 治本修复:原 _extract_call_const_val 只支持 t.XxxType(Constant) 形式, + 治本修复:原 _extract_call_const_val 只支持 XxxType(Constant) 形式, 无法处理 FOREGROUND_WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE 等引用其他 CDefine 的 BinOp 表达式,导致依赖常量无法被预扫描。 现使用 ConstEvaluator.eval_with_symtab 统一求值。 @@ -89,10 +85,10 @@ class LlvmGeneratorMixin: return ConstEvaluator.eval_with_symtab(node, self.SymbolTable) def _is_cdefine_type(TypeInfo: CTypeInfo | None) -> bool: - """判断 CTypeInfo 是否对应 t.CDefine 注解""" + """判断 CTypeInfo 是否对应 CDefine 注解""" return bool(TypeInfo and TypeInfo.BaseType and - ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) - or isinstance(TypeInfo.BaseType, t.CDefine) or TypeInfo.IsDefine)) + ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, TypeSystem.CDefine)) + or isinstance(TypeInfo.BaseType, TypeSystem.CDefine) or TypeInfo.IsDefine)) def _register_cdefine_constant(NameNode: ast.Name, Annotation: ast.expr, Value: ast.expr) -> None: """注册 CDefine 编译期常量(_define_constants + SymbolTable)""" @@ -128,13 +124,13 @@ class LlvmGeneratorMixin: for Node in ast.iter_child_nodes(Tree): if isinstance(Node, ast.AnnAssign) and isinstance(Node.target, ast.Name) and Node.value: TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(Node.annotation) - # 治本修复:检查 BaseType 是否为 t.CDefine 实例/子类,或 IsDefine 标志 - # IsDefine 由 GetCTypeInfo 对 t.CDefine 注解自动设置 + # 治本修复:检查 BaseType 是否为 CDefine 实例/子类,或 IsDefine 标志 + # IsDefine 由 GetCTypeInfo 对 CDefine 注解自动设置 if _is_cdefine_type(TypeInfo): _register_cdefine_constant(Node.target, Node.annotation, Node.value) elif isinstance(Node, ast.ClassDef): # 类体 CDefine 常量(2026-08-10):供方法内裸名(如 Mixin 的 - # ISINSTANCE_CLASS_MAX/MRO_MAX: t.CDefine = N)编译期解析为常量值。 + # ISINSTANCE_CLASS_MAX/MRO_MAX: CDefine = N)编译期解析为常量值。 # 原预扫描只用 iter_child_nodes 扫顶层,类体常量不注册 → 方法内 # 裸名解析为 0 → pool.alloc(8*0) 失败(VPC 编译测试 SUBS-NONE)。 for _citem in Node.body: @@ -152,7 +148,7 @@ class LlvmGeneratorMixin: if _config_mode == "strict": raise _vlog().warning(f"解析类型注释失败: {_e}", "Exception") - if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine)): + if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, TypeSystem.CDefine)) or isinstance(TypeInfo.BaseType, TypeSystem.CDefine)): val: int | str | float | None = _extract_const_value(Node.value) if val is not None: if not hasattr(Gen, '_define_constants'): @@ -293,17 +289,9 @@ class LlvmGeneratorMixin: return call: ast.Call = Node.value if isinstance(call.func, ast.Name): - # 模块级裸名 __llvmir__(...) 等价 c.LLVMIR(...) - if call.func.id == '__llvmir__': + # 模块级 LLVMIR(...) 注入内联 LLVM IR + if call.func.id in ('LLVMIR', '__llvmir__'): self._HandleModuleLevelLLVMIR(call, Gen) - return - if not isinstance(call.func, ast.Attribute): - return - if not isinstance(call.func.value, ast.Name) or call.func.value.id != 'c': - return - func_name: str = call.func.attr - if func_name == 'LLVMIR': - self._HandleModuleLevelLLVMIR(call, Gen) def _HandleModuleLevelLLVMIR(self, Node: ast.Call, Gen: LlvmCodeGenerator) -> None: if not Node.args: @@ -414,14 +402,13 @@ class LlvmGeneratorMixin: if isinstance(Node, ast.Import): for alias in Node.names: name: str = alias.name - if name in ('c', 't'): - continue + # 按常规模块登记(内建标记为裸名,无需 import) self._ImportedModules.add(name) if alias.asname: self.SymbolTable.import_aliases[alias.asname] = name elif isinstance(Node, ast.ImportFrom): module_name: str | None = Node.module - if module_name and module_name not in ('c', 't'): + if module_name: self._ImportedModules.add(module_name) for alias in Node.names: if alias.asname: @@ -493,7 +480,7 @@ class LlvmGeneratorMixin: TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(item.annotation) if TypeInfo is None: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CInt() + TypeInfo.BaseType = TypeSystem.CInt() IsPtr: bool = TypeInfo.IsPtr if not IsPtr: if isinstance(item.annotation, ast.BinOp) and isinstance(item.annotation.op, ast.BitOr): @@ -502,7 +489,7 @@ class LlvmGeneratorMixin: dims: list[int] = [] if hasattr(item.annotation, 'slice') and isinstance(item.annotation.slice, ast.Constant): if isinstance(item.annotation.value, ast.Name): - if IsTModule(item.annotation.value.id, self.SymbolTable): + if item.annotation.value.id == 'CArray': if hasattr(item.annotation, 'slice'): try: dims.append(int(item.annotation.slice.value)) @@ -720,7 +707,7 @@ class LlvmGeneratorMixin: # 每个类建 struct,IR 名前缀取自 `class_sha1_map`(空)→ `_struct_sha1_map` # (Phase2 扫描各 .vpi 得到的"裸类名 → 定义模块 SHA1")。两张表都按**裸类名** # 索引,两个模块各定义同名类时只能留一个:现场 includes/ast/astaux.vp 的 - # `class Keyword(AST)` 与 includes/ast/tokens.vp 的 `class Keyword(t.CEnum)` + # `class Keyword(AST)` 与 includes/ast/tokens.vp 的 `class Keyword(CEnum)` # 同名,`_build_struct_sha1_map` 的"每类只登记一次"判据误用了 sha1 键(恒假、 # 实为后扫到的覆盖先扫到的)⇒ astaux 自己那份被命名成 # `%"fef783da4d24330d.Keyword"`(= tokens 的 sha1)。于是同一类在本模块里出现 diff --git a/lib/core/Translator/PythonParser.py b/lib/core/Translator/PythonParser.py index 177be53..60188e2 100644 --- a/lib/core/Translator/PythonParser.py +++ b/lib/core/Translator/PythonParser.py @@ -6,8 +6,8 @@ import struct from lib.utils.helpers import DetectFileType from lib.core.Handles.HandlesBase import CTypeInfo -from lib.core.SymbolUtils import IsTModule, AnnotationContainsName, ExpandSoftKeywords -from lib.includes import t +from lib.core.SymbolUtils import AnnotationContainsName, ExpandSoftKeywords +from lib.core import TypeSystem from lib.constants.config import mode as _ConfigMode from lib.core.VLogger import get_logger as _vlog @@ -116,18 +116,18 @@ class PythonParserMixin: j += 1 continue elif isinstance(NextNode, ast.AnnAssign): - # 检测 xxx: t.Postdefinition(yyy) 或 xxx: t.CTypedef = xxx 或 xxx: t.CPtr = xxx + # 检测 xxx: Postdefinition(yyy) 或 xxx: CTypedef = xxx 或 xxx: CPtr = xxx if isinstance(NextNode.target, ast.Name): TargetName: str = NextNode.target.id - # 先处理新格式:t.Postdefinition(...) + # 先处理新格式:Postdefinition(...) annotation: ast.expr | None = NextNode.annotation PostdefNode: ast.Call | None = None - # 递归搜索整个注解树,找到 t.Postdefinition(...) 调用 + # 递归搜索整个注解树,找到 Postdefinition(...) 调用 def find_PostdefNode(node: ast.AST) -> ast.Call | None: if isinstance(node, ast.Call): if isinstance(node.func, ast.Attribute): - if hasattr(node.func.value, 'id') and IsTModule(node.func.value.id, self.SymbolTable) and node.func.attr == 'Postdefinition': + if hasattr(node.func.value, 'id') and node.func.attr == 'Postdefinition': return node elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): LeftResult: ast.Call | None = find_PostdefNode(node.left) @@ -139,12 +139,11 @@ class PythonParserMixin: return None PostdefNode = find_PostdefNode(annotation) - # 检查是否找到 t.Postdefinition(...) 调用 + # 检查是否找到 Postdefinition(...) 调用 if PostdefNode: if (isinstance(PostdefNode.func, ast.Attribute) and hasattr(PostdefNode.func, 'value') and - hasattr(PostdefNode.func.value, 'id') and - IsTModule(PostdefNode.func.value.id, self.SymbolTable) and + hasattr(PostdefNode.func.value, 'id') and PostdefNode.func.attr == 'Postdefinition' and PostdefNode.args): # 检查第一个参数是否是当前类名 @@ -164,7 +163,7 @@ class PythonParserMixin: dimensions.append(DimExpr) # 如果没有从 Postdefinition 参数中获取维度,尝试从类型注解中的 Subscript 获取 - # 例如:memory_block_t[MAX_ORDER + 1] | t.CPtr + # 例如:memory_block_t[MAX_ORDER + 1] | CPtr if not dimensions: def extract_subscript_dims(node: ast.AST) -> list[ast.expr]: """递归提取 Subscript 节点的维度""" @@ -180,7 +179,7 @@ class PythonParserMixin: # 递归提取更外层的维度 dims.extend(extract_subscript_dims(node.value)) elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): - # 处理 Type | t.CPtr 的情况,检查左侧 + # 处理 Type | CPtr 的情况,检查左侧 dims.extend(extract_subscript_dims(node.left)) return dims @@ -196,7 +195,7 @@ class PythonParserMixin: value = NextNode.value # 添加到对应的 assignments - # 对于 t.Postdefinition(...),只有包含 CTypedef 或 CPtr 时才视为 typedef 类型 + # 对于 Postdefinition(...),只有包含 CTypedef 或 CPtr 时才视为 typedef 类型 if HasCtypedef or IsPtr: if ClassKey not in self.TypedefAssignments: self.TypedefAssignments[ClassKey] = [] @@ -229,8 +228,8 @@ class PythonParserMixin: # (2026-09-30)】原调用指向的方法全仓无定义 ⇒ 一旦命中即 # `AttributeError`(与 ClassHandle._PreRegisterClassMembers # 同族:死调用,非"未走到")。 - # 现状核实:`__set_default__` 在 TransPyC/lib 内只有 - # t.py 的定义与 StubGen/Converter 的"剥离该调用、保留类型", + # `__set_default__` 在 TransPyC/lib 内只有 + # StubGen/Converter 的"剥离该调用、保留类型", # **没有任何消费端**读取它的 kwargs;includes 全仓亦无源使用。 # 因此这里既不调用幽灵方法,也不静默丢弃源码语义:明确报未支持, # 语义(字段默认值如何落到 class_member_defaults)确定后再实现。 @@ -240,26 +239,19 @@ class PythonParserMixin: f"拒绝静默丢弃该默认值语义)") j += 1 continue - # 再处理旧格式:xxx: t.CTypedef = xxx 或 xxx: t.CPtr = xxx - # 注意:这种格式的 typedef 不应该被合并到结构体定义中, - # 而应该生成独立的 typedef 语句,所以不添加到 TypedefAssignments - elif NextNode.annotation and isinstance(NextNode.annotation, ast.Attribute): - if isinstance(NextNode.annotation.value, ast.Name): - annot_id: str = NextNode.annotation.value.id - annot_attr: str = NextNode.annotation.attr - if annot_id == 't' and NextNode.value: - if isinstance(NextNode.value, ast.Name): - ValueName: str = NextNode.value.id - if ValueName == ClassName: - # 检查是 CTypedef 还是 CPtr - if annot_attr == t.CPtr.__name__: - # t.CPtr 表示指针变量,加入 TypedefAssignments,设置 IsPtr=True - if ClassKey not in self.TypedefAssignments: - self.TypedefAssignments[ClassKey] = [] - self.TypedefAssignments[ClassKey].append((TargetName, True)) - j += 1 - continue - # 注意:t.CTypedef 不在这里处理,由 HandlesAnnAssign 生成独立的 typedef 语句 + # 再处理 xxx: CPtr = xxx:typedef 不合并进结构体定义, + # 而应生成独立的 typedef 语句,故不添加到 TypedefAssignments + elif (NextNode.annotation and isinstance(NextNode.annotation, ast.Name) + and NextNode.annotation.id == TypeSystem.CPtr.__name__): + if NextNode.value and isinstance(NextNode.value, ast.Name): + ValueName: str = NextNode.value.id + if ValueName == ClassName: + # CPtr 表示指针变量,加入 TypedefAssignments,设置 IsPtr=True + if ClassKey not in self.TypedefAssignments: + self.TypedefAssignments[ClassKey] = [] + self.TypedefAssignments[ClassKey].append((TargetName, True)) + j += 1 + continue # 如果不是特殊赋值,停止收集 break @@ -287,20 +279,18 @@ class PythonParserMixin: IsCenum = True break - # 检测是否有 @t.Object 装饰器或继承自 t.Object + # 检测是否有 @Object 装饰器或继承自 Object IsCpythonObject: bool = False if hasattr(node, 'decorator_list') and node.decorator_list: for decorator in node.decorator_list: if isinstance(decorator, ast.Attribute): - if (hasattr(decorator.value, 'id') and - IsTModule(decorator.value.id, self.SymbolTable) and + if (hasattr(decorator.value, 'id') and decorator.attr == 'Object'): IsCpythonObject = True break elif isinstance(decorator, ast.Call): if isinstance(decorator.func, ast.Attribute): - if (hasattr(decorator.func.value, 'id') and - IsTModule(decorator.func.value.id, self.SymbolTable) and + if (hasattr(decorator.func.value, 'id') and decorator.func.attr == 'Object'): IsCpythonObject = True break @@ -315,8 +305,7 @@ class PythonParserMixin: if not IsCpythonObject and hasattr(node, 'bases') and node.bases: for base in node.bases: if isinstance(base, ast.Attribute): - if (hasattr(base.value, 'id') and - IsTModule(base.value.id, self.SymbolTable) and + if (hasattr(base.value, 'id') and base.attr == 'Object'): IsCpythonObject = True break @@ -348,7 +337,7 @@ class PythonParserMixin: continue MemberNode: CTypeInfo = CTypeInfo() MemberNode.Name = MemberName - MemberNode.BaseType = t.CEnum(ClassName) + MemberNode.BaseType = TypeSystem.CEnum(ClassName) # 提取枚举值:优先用显式赋值,否则自动编号 if ItemValue is not None and isinstance(ItemValue, ast.Constant) and isinstance(ItemValue.value, int): MemberNode.value = ItemValue.value @@ -377,7 +366,7 @@ class PythonParserMixin: TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(item.annotation) if TypeInfo is None: TypeInfo = CTypeInfo() - TypeInfo.BaseType = t.CInt() + TypeInfo.BaseType = TypeSystem.CInt() IsPtr: bool = TypeInfo.IsPtr if not IsPtr: if isinstance(item.annotation, ast.BinOp) and isinstance(item.annotation.op, ast.BitOr): @@ -386,7 +375,7 @@ class PythonParserMixin: dims: list[int] = [] if hasattr(item.annotation, 'slice') and isinstance(item.annotation.slice, ast.Constant): if isinstance(item.annotation.value, ast.Name): - if IsTModule(item.annotation.value.id, self.SymbolTable): + if item.annotation.value.id == 'CArray': if hasattr(item.annotation, 'slice'): try: dims.append(int(item.annotation.slice.value)) @@ -421,17 +410,17 @@ class PythonParserMixin: elif isinstance(node, ast.AnnAssign): if isinstance(node.target, ast.Name): VarName: str = node.target.id - # 检查是否是 t.CTypedef 格式,如果是则跳过(由 HandleClassDef 处理) + # 检查是否是 CTypedef 格式,如果是则跳过(由 HandleClassDef 处理) is_ctypedef: bool = False if node.annotation: if isinstance(node.annotation, ast.Attribute): if isinstance(node.annotation.value, ast.Name): - if IsTModule(node.annotation.value.id, self.SymbolTable) and node.annotation.attr == 'CTypedef': + if node.annotation.attr == 'CTypedef': is_ctypedef = True elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.op, ast.BitOr): def _has_ctype(ann: ast.AST) -> bool: if isinstance(ann, ast.Attribute): - return hasattr(ann.value, 'id') and IsTModule(ann.value.id) and ann.attr == 'CTypedef' + return hasattr(ann.value, 'id') and ann.attr == 'CTypedef' if isinstance(ann, ast.BinOp) and isinstance(ann.op, ast.BitOr): return _has_ctype(ann.left) or _has_ctype(ann.right) if isinstance(ann, ast.Subscript): diff --git a/lib/core/TypeAnnotationResolver.py b/lib/core/TypeAnnotationResolver.py index e3538d7..92fa6de 100644 --- a/lib/core/TypeAnnotationResolver.py +++ b/lib/core/TypeAnnotationResolver.py @@ -9,9 +9,9 @@ from typing import TYPE_CHECKING from lib.core.Handles.HandlesBase import CTypeInfo, BuiltinTypeMap, CTypeHelper from lib.core.ConstEvaluator import ConstEvaluator from lib.core.SymbolUtils import ( - IsTModule, IsTModulePath, IsListAnnotation, + IsListAnnotation, ResolveGenericClassSpecName, GetStructSha1MapFromSymtab, GetTCAliasMapFromSymtab) -from lib.includes import t +from lib.core import TypeSystem from lib.constants.config import mode as _config_mode if TYPE_CHECKING: @@ -30,16 +30,16 @@ class TypeAnnotationResolver: """从 AST 节点解析类型注解,独立于 CTypeInfo 数据模型。""" # 编译器内置语法:rawptr(TPC/VPC 双端内置,不可重定义) - # rawptr[T] 固定表示"裸指针,指向原始类型 T"(等价 t.CPtr[T]); - # 单独 rawptr 等价 t.CPtr(void*)。 + # rawptr[T] 固定表示"裸指针,指向原始类型 T"(等价 CPtr[T]); + # 单独 rawptr 等价 CPtr(void*)。 _BUILTIN_ROWPTR_NAME: str = 'rawptr' - _BUILTIN_ROWPTR_VALUE: str = 't.CPtr' + _BUILTIN_ROWPTR_VALUE: str = 'CPtr' @classmethod def _builtin_rawptr_info(cls) -> CTypeInfo: - """返回内置 rawptr 的 CTypeInfo(t.CPtr 语义:BaseType=CVoid, PtrCount=1)""" + """返回内置 rawptr 的 CTypeInfo(CPtr 语义:BaseType=CVoid, PtrCount=1)""" info: CTypeInfo = CTypeInfo() - info.BaseType = t.CVoid() + info.BaseType = TypeSystem.CVoid() info.PtrCount = 1 return info @@ -113,7 +113,7 @@ class TypeAnnotationResolver: # from_imports 注入,故需按源文件扫描兜底。 # 必须同时兼容两种等价写法: # - 语法糖 `typedef 名字 = 类型`(builtins.vp 现用形态) - # - 注解形态 `名字: t.CTypedef = 类型`(stdint.vp 等库模块) + # - 注解形态 `名字: CTypedef = 类型`(stdint.vp 等库模块) # 只认注解形态时语法糖声明全被跳过 → 兜底表为空 → 裸名退化为 # `%"{mod}.名字"*` 假结构体(sizet 曾被当成结构体,BinOp 报 # "Operands must be the same type, got (%"…sizet"*, i64)")。 @@ -124,7 +124,7 @@ class TypeAnnotationResolver: # 既有 `_resolve_builtins_type_str` 的 `depth`/`visited` 只在自身递归内传递; # 而复合值(含 `|` / `[`)分支会经 `from_node` 重新进入 # `_from_node_name → _lookup_builtins_typedef`,把 depth/visited 归零 ⇒ 该方向 - # 可绕过环检测无限递归(A = B | t.CPtr、B = A 一类声明)。此计数器覆盖 + # 可绕过环检测无限递归(A = B | CPtr、B = A 一类声明)。此计数器覆盖 # `_lookup_builtins_typedef → _resolve_builtins_type_str → from_node → …` 全程, # 超上限即判为成环并 fail-fast(不再沿链继续)。合法链通常 ≤ 4 层。 _BUILTINS_CHAIN_MAX_DEPTH: int = 32 @@ -153,11 +153,11 @@ class TypeAnnotationResolver: def _NormalizeTypedefRhsText(text: str) -> str: """把 typedef 右值的 C 式写法归一成规范 `|` 联合文本(供**文本回退路径**使用)。 - 磁盘原文里 `X: t.CTypedef = const str` / `= const uint16*` 的右值带描述符与指针 + 磁盘原文里 `X: CTypedef = const str` / `= const uint16*` 的右值带描述符与指针 后缀,而本路径(_parse_typedef_line → _resolve_builtins_type_str)按表达式文本解析, 故先归一: - - 前导 `const` / `volatile`(可组合) → `t.CConst` / `t.CVolatile` 前缀; - - 末尾 `*` / `**` 串 → 逐层 `| t.CPtr`。 + - 前导 `const` / `volatile`(可组合) → `CConst` / `CVolatile` 前缀; + - 末尾 `*` / `**` 串 → 逐层 `| CPtr`。 不含上述形态的文本原样返回(幂等)。无算术语义风险:typedef 右值不含乘法。 """ s: str = text.strip() @@ -168,7 +168,7 @@ class TypeAnnotationResolver: m: re.Match | None = re.match(r'^(const|volatile)\s+', s) if m is None: break - markers.append('t.CConst' if m.group(1) == 'const' else 't.CVolatile') + markers.append('CConst' if m.group(1) == 'const' else 'CVolatile') s = s[m.end():].lstrip() ptrs: int = 0 while s.endswith('*'): @@ -176,23 +176,23 @@ class TypeAnnotationResolver: ptrs += 1 if not markers and ptrs == 0: return text - parts: list[str] = markers + [s] + ['t.CPtr'] * ptrs + parts: list[str] = markers + [s] + ['CPtr'] * ptrs return ' | '.join(p for p in parts if p) @staticmethod def _parse_typedef_line(stripped: str) -> tuple[str, str] | None: """单行源码文本 → typedef 声明 (名字, 类型值);非 typedef 行返回 None - 兼容 `typedef 名字 = 类型`(语法糖)与 `名字: t.CTypedef = 类型`(注解)。 + 兼容 `typedef 名字 = 类型`(语法糖)与 `名字: CTypedef = 类型`(注解)。 右值的 C 式写法(`const T` / `T*`)经 _NormalizeTypedefRhsText 归一为 `|` 联合。 """ m: re.Match | None = TypeAnnotationResolver._TYPEDEF_SUGAR_RE.match(stripped) if m is not None: return m.group(1), TypeAnnotationResolver._NormalizeTypedefRhsText(m.group(2)) - if ':' not in stripped or 't.CTypedef' not in stripped: + if ':' not in stripped or 'CTypedef' not in stripped: return None name, _, rest = stripped.partition(':') - if 't.CTypedef' not in rest: + if 'CTypedef' not in rest: return None value: str = rest.partition('=')[2].strip() name = name.strip() @@ -262,7 +262,7 @@ class TypeAnnotationResolver: def _scan_library_typedef(cls, mod: str, attr: str) -> str | None: """查库模块源中 typedef 声明,返回类型值(权威定义)或 None - 兼容 `typedef 名字 = 类型`(语法糖)与 `名字: t.CTypedef = 类型`(注解)。 + 兼容 `typedef 名字 = 类型`(语法糖)与 `名字: CTypedef = 类型`(注解)。 """ path: str | None = TypeAnnotationResolver._find_include_file(mod) if path is None: @@ -286,10 +286,10 @@ class TypeAnnotationResolver: def _resolve_builtins_type_str(cls, type_str: str, aliases: dict[str, str], SymbolTable, depth: int = 0, visited: frozenset[str] | None = None) -> CTypeInfo | None: - """解析 builtins typedef 值(支持 t.XXX / mod.attr / 裸名;mod 支持 import 别名) + """解析 builtins typedef 值(支持 XXX / mod.attr / 裸名;mod 支持 import 别名) Args: - type_str: typedef 值(如 t.CPtr / __stdint.size_t / CSizeT / sizet) + type_str: typedef 值(如 CPtr / __stdint.size_t / CSizeT / sizet) aliases: builtins.vp 的 import 别名表(__stdint → stdint) depth: 递归深度守卫(防 typedef 值自引用成环) visited: 本次展开链上已展开的 typedef 名(环检测)。命中环/自引用返回 @@ -317,17 +317,6 @@ class TypeAnnotationResolver: mod = mod.strip() attr = attr.strip() real_mod: str = aliases.get(mod, mod) - # t/c 内建命名空间:**优先按内建类名直接解析**,不依赖调用方 SymbolTable - # 的装配进度(import 注册阶段 t 尚未入表 ⇒ 原先返回 None,被上层误归因为 - # "自引用/循环引用";实测 builtins typedef 'sizet' → 't.CSizeT' 即卡在此处)。 - if real_mod in ('t', 'c'): - _bi: CTypeInfo | None = TypeAnnotationResolver.from_type_name(attr) - if _bi is not None: - return _bi - node = TypeAnnotationResolver._parse_type_expr(type_str) - if node is not None: - return TypeAnnotationResolver.from_node(node, SymbolTable) - return None # 库模块权威 typedef(stdint.size_t → 读 stdint.vp 扫描) lib_val: str | None = TypeAnnotationResolver._scan_library_typedef(real_mod, attr) if lib_val is not None: @@ -341,8 +330,8 @@ class TypeAnnotationResolver: # 裸名:名字本身即类型(t/C 类名、BuiltinTypeMap 的 C 速记名、裸 LLVM 标量名) # → 直接解析;否则它可能是**另一个 typedef 的引用**,沿 builtins typedef 表 # 继续展开到基础类型。 - # 依据:stdint.vp 的 `size_t/SIZE_T: t.CTypedef = sizet` 与 builtins.vp 的 - # `size_t/uzt: t.CTypedef = sizet` 都是"别名 → 权威名 → t 类型"的链式写法, + # 依据:stdint.vp 的 `size_t/SIZE_T: CTypedef = sizet` 与 builtins.vp 的 + # `size_t/uzt: CTypedef = sizet` 都是"别名 → 权威名 → t 类型"的链式写法, # 与 VPC resolve_typedef_or_map 的 CTypedef 表递归(TypeGenResolve.vp:723-734) # 同口径。此前裸名一律走 from_type_name:链中名字命中不到基础类型时退化成 # %"{mod}.{名}"* 假结构体(sizet/size_t → "Type of #N arg mismatch: @@ -355,7 +344,7 @@ class TypeAnnotationResolver: return TypeAnnotationResolver.from_type_name(type_str) seen: frozenset[str] = visited or frozenset() if type_str in seen or chain == type_str: - # 自引用/环(如 `sizet: t.CTypedef = sizet`):无信息可展开,返回 None + # 自引用/环(如 `sizet: CTypedef = sizet`):无信息可展开,返回 None return None return TypeAnnotationResolver._resolve_builtins_type_str( chain, aliases, SymbolTable, depth + 1, seen | {type_str}) @@ -375,8 +364,8 @@ class TypeAnnotationResolver: return True cls: type | None = CTypeHelper.GetTModuleCType(name) if cls is None: - cls = getattr(t, name, None) - return isinstance(cls, type) and issubclass(cls, t.CType) and cls is not t.CType + cls = getattr(TypeSystem, name, None) + return isinstance(cls, type) and issubclass(cls, TypeSystem.CType) and cls is not TypeSystem.CType @staticmethod def _parse_type_expr(text: str) -> ast.AST | None: @@ -394,7 +383,7 @@ class TypeAnnotationResolver: @classmethod def builtins_typedef_value(cls, TypeName: str) -> str | None: - """返回 builtins.vp 中 CTypedef 声明的原始类型值(如 rawptr → 't.CPtr') + """返回 builtins.vp 中 CTypedef 声明的原始类型值(如 rawptr → 'CPtr') 供 stub 生成 / 类型字符串消费端判断"base[arg]"下标是否为 builtins 指针 typedef(rawptr[AST] → AST*),防止字符串化产物被误建为 phantom 结构体。 @@ -438,7 +427,7 @@ class TypeAnnotationResolver: f"builtins typedef 解析链成环或过深(>{cls._BUILTINS_CHAIN_MAX_DEPTH} 层)," f"解析 '{TypeName}' 时终止:includes/builtins.vp 中相关 typedef 声明" f"(含 `|` / `[...]` 复合值)互相引用成环。请改为指向真实基础类型" - f"(如 t.CSizeT),或断开环上引用。") + f"(如 CSizeT),或断开环上引用。") cls._builtins_failure_cache[TypeName] = _err raise ValueError(_err) data: dict = cls._scan_builtins() @@ -447,13 +436,13 @@ class TypeAnnotationResolver: return None info: CTypeInfo | None = cls._resolve_builtins_type_str(type_str, data['aliases'], SymbolTable) if info is None: - # 不再一律归因"自引用/循环引用"(那正是把 t.CSizeT 解析失败误报成环、 + # 不再一律归因"自引用/循环引用"(那正是把 CSizeT 解析失败误报成环、 # 把人引向错误方向的根因):把声明值与该值解析失败的形态如实报出。 _err = ( f"builtins typedef '{TypeName}' 无法解析到基础类型:includes/builtins.vp " - f"声明 '{TypeName}: t.CTypedef = {type_str}',其值 '{type_str}' 解析失败" + f"声明 '{TypeName}: CTypedef = {type_str}',其值 '{type_str}' 解析失败" f"(既不是内建类型名,也不是链上可展开的 typedef)。" - f"请把该声明指向真实类型(如 t.CSizeT),或确认该类型名存在。") + f"请把该声明指向真实类型(如 CSizeT),或确认该类型名存在。") cls._builtins_failure_cache[TypeName] = _err raise ValueError(_err) return info @@ -494,21 +483,21 @@ class TypeAnnotationResolver: _R: CTypeInfo = _Cand.Copy() _R.IsTypedef = True if _R.BaseType is None: - _R.BaseType = t._CTypedef(TypeName) + _R.BaseType = TypeSystem._CTypedef(TypeName) return _R if getattr(_Cand, 'IsStruct', False) or getattr(_Cand, 'IsRenum', False): # 结构体表示与本文件既有 promotion(_from_node_name / _from_node_attribute - # 的 `BaseType = t.CStruct(name=...); IsStruct = True`)**逐字同口径**: + # 的 `BaseType = CStruct(name=...); IsStruct = True`)**逐字同口径**: # 类引用不额外加指针层(PtrCount 保持 0)——本文件里 `rawptr[X]` 的层数 # 由 rawptr 分支自己 +1,若此处再加一层会得到 `X**`。 _R = CTypeInfo() - _R.BaseType = t.CStruct(name=TypeName) + _R.BaseType = TypeSystem.CStruct(name=TypeName) _R.IsStruct = True _R.Name = TypeName return _R if getattr(_Cand, 'IsEnum', False): _R = CTypeInfo() - _R.BaseType = t.CInt() + _R.BaseType = TypeSystem.CInt() _R.IsEnum = True _R.Name = TypeName return _R @@ -518,39 +507,44 @@ class TypeAnnotationResolver: def _from_node_name(Node: ast.Name, SymbolTable: dict | SymbolTable) -> CTypeInfo: """处理 ast.Name 节点""" TypeName: str = Node.id - # 编译器内置语法 rawptr(不可重定义):单独 rawptr 等价 t.CPtr(void*), + # 编译器内置语法 rawptr(不可重定义):单独 rawptr 等价 CPtr(void*), # 优先于 SymbolTable/任何 typedef 声明。 if TypeName == TypeAnnotationResolver._BUILTIN_ROWPTR_NAME: return TypeAnnotationResolver._builtin_rawptr_info() + if TypeName in ('CRef', 'CTempRef'): + Result: CTypeInfo = CTypeInfo() + Result.PtrCount = 1 + Result.BaseType = TypeSystem.CVoid() + return Result TypeObj: type | None = CTypeHelper.GetTModuleCType(TypeName) if TypeObj is None: - TypeObj = getattr(t, TypeName, None) - if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType) and TypeObj is not t.CType: - if TypeObj == t.CPtr: + TypeObj = getattr(TypeSystem, TypeName, None) + if isinstance(TypeObj, type) and issubclass(TypeObj, TypeSystem.CType) and TypeObj is not TypeSystem.CType: + if TypeObj == TypeSystem.CPtr: Result: CTypeInfo = CTypeInfo() Result.PtrCount = 1 - Result.BaseType = t.CVoid() + Result.BaseType = TypeSystem.CVoid() return Result - if TypeObj == t.State: + if TypeObj == TypeSystem.State: Result: CTypeInfo = CTypeInfo() Result.IsState = True - Result.BaseType = t.CVoid() + Result.BaseType = TypeSystem.CVoid() return Result - Inst: t.CType = TypeObj() + Inst: TypeSystem.CType = TypeObj() Result: CTypeInfo = CTypeInfo() Result.Name = type(Inst).__name__ # 存储类修饰符(CExtern, CExport, CInline, CThreadLocal 等): # position 含 STORAGE_CLASS 且不含 BASE → 纯修饰符,无实际类型 - if t.CType.STORAGE_CLASS in TypeObj.position and t.CType.BASE not in TypeObj.position: - Result.BaseType = t.CVoid() + if TypeSystem.CType.STORAGE_CLASS in TypeObj.position and TypeSystem.CType.BASE not in TypeObj.position: + Result.BaseType = TypeSystem.CVoid() Result.Storage = Inst return Result # 类型限定符(CConst, CVolatile 等) - if t.CType.TYPE_QUALIFIER in TypeObj.position and t.CType.BASE not in TypeObj.position: - Result.BaseType = t.CVoid() - if TypeObj == t.CConst: + if TypeSystem.CType.TYPE_QUALIFIER in TypeObj.position and TypeSystem.CType.BASE not in TypeObj.position: + Result.BaseType = TypeSystem.CVoid() + if TypeObj == TypeSystem.CConst: Result.DataConst = True - elif TypeObj == t.CVolatile: + elif TypeObj == TypeSystem.CVolatile: Result.DataVolatile = True return Result Result.BaseType = TypeObj @@ -572,7 +566,7 @@ class TypeAnnotationResolver: if Entry: if isinstance(Entry, CTypeInfo): if Entry.IsTypedef: - if Entry.BaseType and (not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0): + if Entry.BaseType and (not isinstance(Entry.BaseType, (TypeSystem._CTypedef,)) or Entry.PtrCount > 0): Result = Entry.Copy() Result.IsTypedef = True Result.Name = TypeName @@ -614,18 +608,18 @@ class TypeAnnotationResolver: return Entry if Entry.IsEnum: Result = CTypeInfo() - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.IsEnum = True Result.Name = TypeName return Result if Entry.IsExceptionClass: Result = CTypeInfo() - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.IsExceptionClass = True Result.Name = TypeName return Result if Entry.BaseType is None and (Entry.IsStruct or Entry.Name): - Entry.BaseType = t.CStruct(name=TypeName) + Entry.BaseType = TypeSystem.CStruct(name=TypeName) Entry.IsStruct = True if (Entry.BaseType is None and not Entry.IsStruct and not Entry.IsEnum and not Entry.IsTypedef and not Entry.IsCpythonObject and not Entry.Name): @@ -665,13 +659,13 @@ class TypeAnnotationResolver: Result.Name = TypeName return Result Result = CTypeInfo() - Result.BaseType = t._CTypedef(TypeName) + Result.BaseType = TypeSystem._CTypedef(TypeName) Result.IsTypedef = True Result.Name = TypeName return Result # 检查 t 类型别名(from t import CInt as myint) - if hasattr(SymbolTable, '_t_type_symbols'): - t_cls = SymbolTable._t_type_symbols.get(TypeName) + if hasattr(SymbolTable, '_builtin_type_symbols'): + t_cls = SymbolTable._builtin_type_symbols.get(TypeName) if t_cls is not None: Result = CTypeInfo() Result.BaseType = t_cls @@ -679,7 +673,7 @@ class TypeAnnotationResolver: # 特殊处理 str 类型,它应该是 char*(指针) if TypeName in ('str', 'bytes'): Result = CTypeInfo() - Result.BaseType = t.CChar() + Result.BaseType = TypeSystem.CChar() Result.PtrCount = 1 return Result # [builtins 最后匹配] 常规路径全部 miss 后的最终兜底: @@ -712,17 +706,15 @@ class TypeAnnotationResolver: if _config_mode == "strict": warnings.warn(f"异常被忽略: {_e}") return Result - if isinstance(Node.func, ast.Attribute): - if isinstance(Node.func.value, ast.Name) and IsTModule(Node.func.value.id, SymbolTable): - if Node.func.attr == 'Bit' and len(Node.args) > 0: - Result: CTypeInfo = CTypeInfo() - Result.BaseType = t.CInt() - Result.IsBitField = True - if isinstance(Node.args[0], ast.Constant) and isinstance(Node.args[0].value, int): - Result.BitWidth = Node.args[0].value - else: - Result.BitWidth = 1 - return Result + if isinstance(Node.func, ast.Name) and Node.func.id == 'Bit' and len(Node.args) > 0: + Result: CTypeInfo = CTypeInfo() + Result.BaseType = TypeSystem.CInt() + Result.IsBitField = True + if isinstance(Node.args[0], ast.Constant) and isinstance(Node.args[0].value, int): + Result.BitWidth = Node.args[0].value + else: + Result.BitWidth = 1 + return Result return CTypeInfo() @staticmethod @@ -736,10 +728,10 @@ class TypeAnnotationResolver: Result.IsState = True NonStateInfo: CTypeInfo = LeftInfo if not LeftInfo.IsState else RightInfo StateInfo: CTypeInfo = LeftInfo if LeftInfo.IsState else RightInfo - if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0): + if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (TypeSystem._CTypedef,)) or NonStateInfo.PtrCount > 0): Result.BaseType = NonStateInfo.BaseType elif NonStateInfo.IsTypedef and NonStateInfo.Name: - if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0): + if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (TypeSystem._CTypedef,)) or NonStateInfo.PtrCount > 0): Result.BaseType = NonStateInfo.BaseType Result.PtrCount = NonStateInfo.PtrCount Result.IsTypedef = True @@ -747,20 +739,20 @@ class TypeAnnotationResolver: if NonStateInfo.OriginalType: Result.OriginalType = NonStateInfo.OriginalType else: - Result.BaseType = t.CStruct(name=NonStateInfo.Name) + Result.BaseType = TypeSystem.CStruct(name=NonStateInfo.Name) Result.IsStruct = True Result.IsTypedef = True Result.Name = NonStateInfo.Name if NonStateInfo.OriginalType: Result.OriginalType = NonStateInfo.OriginalType else: - Result.BaseType = t.CVoid() + Result.BaseType = TypeSystem.CVoid() Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) if not Result.Storage: - Result.Storage = t.CExport() - if LeftInfo.Storage and not isinstance(LeftInfo.Storage, t.CExport): + Result.Storage = TypeSystem.CExport() + if LeftInfo.Storage and not isinstance(LeftInfo.Storage, TypeSystem.CExport): Result.Storage = LeftInfo.Storage - elif RightInfo.Storage and not isinstance(RightInfo.Storage, t.CExport): + elif RightInfo.Storage and not isinstance(RightInfo.Storage, TypeSystem.CExport): Result.Storage = RightInfo.Storage if LeftInfo.DataConst or RightInfo.DataConst: Result.DataConst = True @@ -770,37 +762,37 @@ class TypeAnnotationResolver: if LeftInfo.IsPtr or RightInfo.IsPtr: Result = CTypeInfo() - # 当双方都是指针时(如 (AST | t.CPtr) | t.CPtr),PtrCount 应相加 + # 当双方都是指针时(如 (AST | CPtr) | CPtr),PtrCount 应相加 # 而非取 max,否则 AST** 会被折叠为 AST*,导致对象切片问题 if LeftInfo.IsPtr and RightInfo.IsPtr: Result.PtrCount = LeftInfo.PtrCount + RightInfo.PtrCount - # BaseType 优先取非 void 侧(如 AST),而非 t.CPtr 的 void - if LeftInfo.BaseType and not isinstance(LeftInfo.BaseType, t.CVoid): + # BaseType 优先取非 void 侧(如 AST),而非 CPtr 的 void + if LeftInfo.BaseType and not isinstance(LeftInfo.BaseType, TypeSystem.CVoid): Result.BaseType = LeftInfo.BaseType - elif RightInfo.BaseType and not isinstance(RightInfo.BaseType, t.CVoid): + elif RightInfo.BaseType and not isinstance(RightInfo.BaseType, TypeSystem.CVoid): Result.BaseType = RightInfo.BaseType else: - Result.BaseType = t.CUnsignedChar() + Result.BaseType = TypeSystem.CUnsignedChar() else: Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) NonPtrInfo = LeftInfo if not LeftInfo.IsPtr else RightInfo PtrInfo = RightInfo if RightInfo.IsPtr else LeftInfo - if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0): + if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (TypeSystem._CTypedef,)) or NonPtrInfo.PtrCount > 0): Result.BaseType = NonPtrInfo.BaseType elif NonPtrInfo.IsTypedef and NonPtrInfo.Name: - if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0): + if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (TypeSystem._CTypedef,)) or NonPtrInfo.PtrCount > 0): Result.BaseType = NonPtrInfo.BaseType Result.IsTypedef = True Result.Name = NonPtrInfo.Name if NonPtrInfo.OriginalType: Result.OriginalType = NonPtrInfo.OriginalType else: - Result.BaseType = t.CStruct(name=NonPtrInfo.Name) + Result.BaseType = TypeSystem.CStruct(name=NonPtrInfo.Name) Result.IsStruct = True - elif PtrInfo.BaseType and (not isinstance(PtrInfo.BaseType, (t._CTypedef,)) or PtrInfo.PtrCount > 0): + elif PtrInfo.BaseType and (not isinstance(PtrInfo.BaseType, (TypeSystem._CTypedef,)) or PtrInfo.PtrCount > 0): Result.BaseType = PtrInfo.BaseType else: - Result.BaseType = t.CUnsignedChar() + Result.BaseType = TypeSystem.CUnsignedChar() if LeftInfo.DataConst or RightInfo.DataConst: Result.DataConst = True if LeftInfo.VarConst or RightInfo.VarConst: @@ -819,9 +811,9 @@ class TypeAnnotationResolver: Result = CTypeInfo() BaseTypeSide = LeftInfo if not LeftInfo.DataConst else RightInfo QualSide = LeftInfo if LeftInfo.DataConst else RightInfo - Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType + Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, TypeSystem.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType if not Result.BaseType: - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.DataConst = True Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) if LeftInfo.VarConst or RightInfo.VarConst: @@ -838,9 +830,9 @@ class TypeAnnotationResolver: Result = CTypeInfo() BaseTypeSide = LeftInfo if not LeftInfo.DataVolatile else RightInfo QualSide = LeftInfo if LeftInfo.DataVolatile else RightInfo - Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType + Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, TypeSystem.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType if not Result.BaseType: - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.DataVolatile = True Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) if LeftInfo.VarConst or RightInfo.VarConst: @@ -855,15 +847,15 @@ class TypeAnnotationResolver: Result = CTypeInfo() BaseTypeSide = LeftInfo if not LeftInfo.Storage else RightInfo StorageSide = LeftInfo if LeftInfo.Storage else RightInfo - # CExtern | CExport 等价于 t.State:两边都有 Storage 时设置 IsState + # CExtern | CExport 等价于 State:两边都有 Storage 时设置 IsState if BaseTypeSide.IsState or StorageSide.IsState or (LeftInfo.Storage and RightInfo.Storage): Result.IsState = True - Result.BaseType = t.CVoid() + Result.BaseType = TypeSystem.CVoid() Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage return Result - Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else StorageSide.BaseType + Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, TypeSystem.CVoid) or BaseTypeSide.PtrCount > 0) else StorageSide.BaseType if not Result.BaseType: - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) if LeftInfo.DataConst or RightInfo.DataConst: @@ -872,32 +864,32 @@ class TypeAnnotationResolver: Result.VarConst = True return Result - # 检查是否有位域类型 (t.Bit) + # 检查是否有位域类型 (Bit) if LeftInfo.IsBitField: Result = CTypeInfo() - Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else t.CInt() + Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else TypeSystem.CInt() Result.IsBitField = True Result.BitWidth = LeftInfo.BitWidth return Result if RightInfo.IsBitField: Result = CTypeInfo() - Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else t.CInt() + Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else TypeSystem.CInt() Result.IsBitField = True Result.BitWidth = RightInfo.BitWidth return Result - # 处理字节序类型 (t.BigEndian, t.LittleEndian) + # 处理字节序类型 (BigEndian, LittleEndian) # 合并两侧:保留非字节序侧的实际类型(如 CUInt64T),取字节序侧的 ByteOrder if LeftInfo.ByteOrder or RightInfo.ByteOrder: Result = CTypeInfo() ByteOrderSide: CTypeInfo = LeftInfo if LeftInfo.ByteOrder else RightInfo OtherSide: CTypeInfo = RightInfo if LeftInfo.ByteOrder else LeftInfo - if OtherSide.BaseType and (not isinstance(OtherSide.BaseType, (t._CTypedef,)) or OtherSide.PtrCount > 0): + if OtherSide.BaseType and (not isinstance(OtherSide.BaseType, (TypeSystem._CTypedef,)) or OtherSide.PtrCount > 0): Result.BaseType = OtherSide.BaseType - elif ByteOrderSide.BaseType and (not isinstance(ByteOrderSide.BaseType, (t._CTypedef,)) or ByteOrderSide.PtrCount > 0): + elif ByteOrderSide.BaseType and (not isinstance(ByteOrderSide.BaseType, (TypeSystem._CTypedef,)) or ByteOrderSide.PtrCount > 0): Result.BaseType = ByteOrderSide.BaseType else: - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.ByteOrder = LeftInfo.ByteOrder or RightInfo.ByteOrder Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) return Result @@ -915,7 +907,7 @@ class TypeAnnotationResolver: return Result if LeftInfo.IsTypedef and RightInfo.BaseType: - if LeftInfo.BaseType and (not isinstance(LeftInfo.BaseType, (t._CTypedef,)) or LeftInfo.PtrCount > 0): + if LeftInfo.BaseType and (not isinstance(LeftInfo.BaseType, (TypeSystem._CTypedef,)) or LeftInfo.PtrCount > 0): Result = LeftInfo.Copy() Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) if RightInfo.Storage: @@ -923,7 +915,7 @@ class TypeAnnotationResolver: return Result return RightInfo if RightInfo.IsTypedef and LeftInfo.BaseType: - if RightInfo.BaseType and (not isinstance(RightInfo.BaseType, (t._CTypedef,)) or RightInfo.PtrCount > 0): + if RightInfo.BaseType and (not isinstance(RightInfo.BaseType, (TypeSystem._CTypedef,)) or RightInfo.PtrCount > 0): Result = RightInfo.Copy() Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount) if LeftInfo.Storage: @@ -942,9 +934,9 @@ class TypeAnnotationResolver: """处理 ast.Subscript 节点""" base: ast.AST = Node.value if isinstance(base, ast.Attribute): - if isinstance(base.value, ast.Name) and IsTModule(base.value.id, SymbolTable) and base.attr == 'Bit': + if isinstance(base.value, ast.Name) and base.attr == 'Bit': Result: CTypeInfo = CTypeInfo() - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.IsBitField = True if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int): Result.BitWidth = Node.slice.value @@ -972,14 +964,14 @@ class TypeAnnotationResolver: else: Result.PtrCount += 1 else: - # 单参数 t.CArray[T](= t.CArray[T, None]):长度自动推导数组。 + # 单参数 CArray[T](= CArray[T, None]):长度自动推导数组。 # 指针位置语义为"元素指针" Ptr(T),需在元素类型上再加一层指针。 # 与裸名 CArray[T](HandlesTypeMerge.CollectAll 的 # `ElementType.PtrCount + 1`)、stub 侧(LLVMTypeMapper # IsListAnnotation 的 `elem_type + '*'`)、声明端 # (DeclarationGenerator `[0 x T]` → _decay_array_to_ptr = T*) # 以及 VPC(TypeGenResolve 单参 → Ptr(elem_ty))同口径。 - # 此前缺这一层:t.CArray[str] 得 i8*(即 str 本身), + # 此前缺这一层:CArray[str] 得 i8*(即 str 本身), # result[k] 退化成 i8 → 写字符串指针触发 ptr→int fail-fast。 Result.PtrCount += 1 if ElemInfo.IsPtr and not ElemInfo.ArrayDims: @@ -987,7 +979,7 @@ class TypeAnnotationResolver: return Result # 函数指针构造子的两种书写形态逐点等价(对齐 VPC # TypeGenResolve._IsCallableSubscriptValue): - # t.Callable[...] / c.Callable[...] → 模块限定 Attribute + # Callable[...] / Callable[...] → 模块限定 Attribute # callable[...] / Callable[...] → 内建裸名(无需 import) # 裸名形态此前落进下方泛型特化兜底(ResolveGenericClassSpecName)未命中 ⇒ # 空 CTypeInfo ⇒ 槽位类型退化 i32(现场 Repl.vp:307 @@ -1005,9 +997,9 @@ class TypeAnnotationResolver: # 裸名只在注解位置当函数指针构造子(非类型位置仍是普通标识符) IsBareCallable = True if isinstance(base, ast.Attribute) or IsBareCallable: - if (not IsBareCallable) and parts and IsTModule(parts[0], SymbolTable) and parts[-1] == t.CPtr.__name__: + if (not IsBareCallable) and parts and parts[-1] == TypeSystem.CPtr.__name__: Result: CTypeInfo = CTypeInfo() - Result.BaseType = t.CVoid() + Result.BaseType = TypeSystem.CVoid() Result.PtrCount = 1 slice_node: ast.AST = Node.slice if isinstance(slice_node, ast.Subscript): @@ -1015,25 +1007,25 @@ class TypeAnnotationResolver: if InnerInfo: if InnerInfo.PtrCount > 0: Result.PtrCount += InnerInfo.PtrCount - if InnerInfo.BaseType and not isinstance(InnerInfo.BaseType, t.CVoid): + if InnerInfo.BaseType and not isinstance(InnerInfo.BaseType, TypeSystem.CVoid): Result.BaseType = InnerInfo.BaseType elif isinstance(slice_node, ast.Attribute): SliceInfo: CTypeInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable) if SliceInfo: if SliceInfo.IsPtr: Result.PtrCount += SliceInfo.PtrCount - elif SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid): + elif SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, TypeSystem.CVoid): Result.BaseType = SliceInfo.BaseType elif isinstance(slice_node, ast.Name): - SliceType: type | None = getattr(t, slice_node.id, None) - if SliceType == t.CPtr: + SliceType: type | None = getattr(TypeSystem, slice_node.id, None) + if SliceType == TypeSystem.CPtr: Result.PtrCount += 1 else: SliceInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable) - if SliceInfo and SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid): + if SliceInfo and SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, TypeSystem.CVoid): Result.BaseType = SliceInfo.BaseType return Result - if IsBareCallable or (parts and IsTModule(parts[0], SymbolTable) and parts[-1] == 'Callable'): + if IsBareCallable or (parts and parts[-1] == 'Callable'): Result = CTypeInfo() Result.IsFuncPtr = True slice_node = Node.slice @@ -1047,14 +1039,14 @@ class TypeAnnotationResolver: ParamTypeInfo = TypeAnnotationResolver.from_node(elt, SymbolTable) if ParamTypeInfo: ParamTypes.append(('', ParamTypeInfo)) - # 空参数表 `t.Callable[[], R]` 语义 = 零形参:LLVM 端即 `R ()*`, + # 空参数表 `Callable[[], R]` 语义 = 零形参:LLVM 端即 `R ()*`, # 调用点按零实参间接 call。此前在此注入 void 占位形参 → 得 # `R (void)*`(void 作形参本身不是合法 LLVM 函数类型),调用点 # 实参个数(0) 与形参个数(1) 不符 → llvmlite CallInstr - # `arg = args[i]` IndexError(Repl.vp 模块级 t.Callable 槽 + # `arg = args[i]` IndexError(Repl.vp 模块级 Callable 槽 # `ReplFragFn()` 翻译崩溃根因);与本文件另三处 Callable 形态 # (:378 / :422 / :471)的 `FuncPtrParams = []` 口径统一。 - # 非 List 形态(遗留写法 t.Callable[A, R])保留原 void 占位行为。 + # 非 List 形态(遗留写法 Callable[A, R])保留原 void 占位行为。 if not ParamTypes and not _ParamsIsList: ParamTypes.append(('', TypeAnnotationResolver.from_type_name('void'))) Result.FuncPtrParams = ParamTypes @@ -1062,7 +1054,7 @@ class TypeAnnotationResolver: Result.FuncPtrReturn = ReturnTypeInfo if ReturnTypeInfo else CTypeInfo.VoidTypeInfo() return Result # [builtins 最后匹配] 裸名 builtins typedef 下标(rawptr[int] → Ptr(int)): - # 与 VPC Subscript 分支同口径——base 是 builtins typedef(rawptr → t.CPtr), + # 与 VPC Subscript 分支同口径——base 是 builtins typedef(rawptr → CPtr), # 结果 = 切片类型外包 base 的指针层数。 if isinstance(base, ast.Name): base_info: CTypeInfo | None = TypeAnnotationResolver._lookup_builtins_typedef(base.id, SymbolTable) @@ -1070,16 +1062,16 @@ class TypeAnnotationResolver: slice_node = Node.slice SliceInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable) Result = CTypeInfo() - Result.BaseType = SliceInfo.BaseType if (SliceInfo and SliceInfo.BaseType) else t.CVoid() + Result.BaseType = SliceInfo.BaseType if (SliceInfo and SliceInfo.BaseType) else TypeSystem.CVoid() Result.PtrCount = (SliceInfo.PtrCount if SliceInfo else 0) + base_info.PtrCount return Result # 泛型类下标(单/多参):list[str] / dict[str][int] / 用户泛型 Box[Node]。 # 特化名与声明端(DeclarationGenerator 泛型分支)同口径,见 # SymbolUtils.ResolveGenericClassSpecName。此前单参泛型下标在下方直接落到 # "未知类型"空 CTypeInfo ⇒ 形参/成员类型退化成 i32 或 void 指针链 - # (现场:type_args: list[str]* 的形参 i32;CTypedefNames: list[str] | t.CPtr → i8*)。 + # (现场:type_args: list[str]* 的形参 i32;CTypedefNames: list[str] | CPtr → i8*)。 # 表示口径与本文件既有结构体 promotion 逐字一致(BaseType=CStruct + IsStruct + - # Name,PtrCount 保持 0):`X | t.CPtr` 由 _from_node_binop 取 max → 1 层, + # Name,PtrCount 保持 0):`X | CPtr` 由 _from_node_binop 取 max → 1 层, # `rawptr[X]` 由上方分支 +1 → 1 层,均与 declare 侧 %"{sha}.X[*]"* 一致。 _Spec: str | None = ResolveGenericClassSpecName( Node, SymbolTable, @@ -1087,7 +1079,7 @@ class TypeAnnotationResolver: GetTCAliasMapFromSymtab(SymbolTable)) if _Spec: Result = CTypeInfo() - Result.BaseType = t.CStruct(name=_Spec) + Result.BaseType = TypeSystem.CStruct(name=_Spec) Result.IsStruct = True Result.Name = _Spec return Result @@ -1116,6 +1108,10 @@ class TypeAnnotationResolver: else: return CTypeInfo() + if isinstance(Current, ast.Name) and Current.id in ("t", "c"): + raise TypeError( + f"[TPC] 类型注解不再接受 \"{Current.id}.\" 模块前缀;" + f"请直接写内建类型名(如 CPtr、CInt、CArray)。") # 解析 import 别名: 如 import vpsdk.window as window -> window -> vpsdk.window if ModulePath: resolved: bool = False @@ -1130,77 +1126,6 @@ class TypeAnnotationResolver: if resolved_name: ModulePath = resolved_name - if ModulePath and IsTModulePath(ModulePath): - # 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`):非真实类,仅按名字 - # 识别为「一层指针」(与 t.CPtr 同形),使联合形态 `T | t.CRef` 解析为 T*、 - # `void | t.CRef` 解析为 void*(i8*)。模式语义(ref/temp)由注解侧识别。 - if TypeName in ('CRef', 'CTempRef'): - Info: CTypeInfo = CTypeInfo() - Info.PtrCount = 1 - Info.BaseType = t.CVoid - return Info - TypeClass: type | None = CTypeHelper.GetTModuleCType(TypeName) - if TypeClass is None: - TypeClass = getattr(t, TypeName, None) - if TypeClass is not None and TypeClass.HasPosition(t.CType.POINTER): - Info: CTypeInfo = CTypeInfo() - Info.PtrCount = 1 - if TypeClass == t.CArrayPtr: - Info.IsArrayPtr = True - Info.BaseType = t.CVoid - return Info - if TypeClass is not None and TypeClass.IsStorageClass(): - Info: CTypeInfo = CTypeInfo() - Info.Storage = TypeClass() - if TypeClass == t.State: - Info.IsState = True - Info.BaseType = t.CVoid() - return Info - if TypeClass is not None and TypeClass.IsTypeQualifier(): - Info: CTypeInfo = CTypeInfo() - if TypeClass == t.CConst: - Info.DataConst = True - elif TypeClass == t.CVolatile: - Info.DataVolatile = True - return Info - if TypeClass is not None and TypeClass in (t.BigEndian, t.LittleEndian): - Result: CTypeInfo = CTypeInfo() - Result.BaseType = t.CInt() - Result.ByteOrder = 'big' if TypeClass == t.BigEndian else 'little' - return Result - if (TypeClass is not None - and isinstance(TypeClass, type) - and issubclass(TypeClass, t.CType) - and TypeClass is not t.CType - and TypeClass.HasPosition(t.CType.BASE)): - if TypeClass == t.State: - Result: CTypeInfo = CTypeInfo() - Result.IsState = True - Result.BaseType = t.CVoid() - return Result - Inst: t.CType = TypeClass() - Result: CTypeInfo = CTypeInfo() - Result.BaseType = TypeClass - Result.Name = type(Inst).__name__ - if hasattr(Inst, 'IsSigned'): - Result.IsSigned = Inst.IsSigned - return Result - CNAME: str | None = CTypeHelper.GetCName(TypeName) - if CNAME: - return TypeAnnotationResolver.from_type_name(CNAME) - - # 处理字节序类型 - if TypeName == 'BigEndian': - Result = CTypeInfo() - Result.BaseType = t.CInt() - Result.ByteOrder = 'big' - return Result - if TypeName == 'LittleEndian': - Result = CTypeInfo() - Result.BaseType = t.CInt() - Result.ByteOrder = 'little' - return Result - FullName: str = f"{ModulePath}.{TypeName}" if ModulePath else TypeName if TypeName in SymbolTable: @@ -1208,24 +1133,24 @@ class TypeAnnotationResolver: if Entry and Entry.IsTypedef: Resolved: CTypeInfo = Entry.Copy() if Resolved.BaseType is None: - Resolved.BaseType = t._CTypedef(TypeName) + Resolved.BaseType = TypeSystem._CTypedef(TypeName) return Resolved if Entry and Entry.IsEnum: Result: CTypeInfo = CTypeInfo() - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.IsEnum = True Result.Name = TypeName return Result if Entry and Entry.IsExceptionClass: Result: CTypeInfo = CTypeInfo() - Result.BaseType = t.CInt() + Result.BaseType = TypeSystem.CInt() Result.IsExceptionClass = True Result.Name = TypeName return Result if Entry: Result: CTypeInfo = Entry.Copy() if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name): - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.IsStruct = True if (Result.BaseType is None and not Result.IsStruct and not Result.IsEnum and not Result.IsTypedef and not Result.IsCpythonObject and not Result.Name): @@ -1251,7 +1176,7 @@ class TypeAnnotationResolver: # 命名口径见 HandlesClassDef._EmitNestedClassDefs —— 嵌套类以扁平名 # `{外类}_{内类}` 发射,并由 _RegisterNestedClassName 把扁平名与 `外类.内类` # 一并插入 SymbolTable。本分支按**扁平名**取条目:BaseType/Name 必须是扁平名 - # (若走下方 FullName 分支,会按短名拼出 `t.CStruct(name='Inner')`,与 + # (若走下方 FullName 分支,会按短名拼出 `CStruct(name='Inner')`,与 # 声明端的 `%"{sha}.外类_内类"` 不同源 ⇒ 布局/字段偏移分叉)。 if ModulePath and TypeName: NestedKey: str = f"{ModulePath}_{TypeName}" @@ -1261,7 +1186,7 @@ class TypeAnnotationResolver: Result = NestedEntry.Copy() Result.Name = NestedKey if Result.BaseType is None: - Result.BaseType = t.CStruct(name=NestedKey) + Result.BaseType = TypeSystem.CStruct(name=NestedKey) Result.IsStruct = True return Result @@ -1269,7 +1194,7 @@ class TypeAnnotationResolver: Info: CTypeInfo = SymbolTable[FullName] if Info and Info.IsTypedef: # 优先用 BaseType 解析(如 VOIDPTR 已解析为 BaseType=CVoid, PtrCount=1) - if Info.BaseType and (not isinstance(Info.BaseType, (t._CTypedef,)) or Info.PtrCount > 0): + if Info.BaseType and (not isinstance(Info.BaseType, (TypeSystem._CTypedef,)) or Info.PtrCount > 0): Result = Info.Copy() Result.IsTypedef = True Result.Name = FullName @@ -1304,14 +1229,14 @@ class TypeAnnotationResolver: return Resolved # 回退:保持原逻辑但设置 Name = FullName(供后续 TypeConvert 查找) Result: CTypeInfo = CTypeInfo() - Result.BaseType = t._CTypedef(TypeName) + Result.BaseType = TypeSystem._CTypedef(TypeName) Result.IsTypedef = True Result.Name = FullName return Result if Info: Result: CTypeInfo = Info.Copy() if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name): - Result.BaseType = t.CStruct(name=TypeName) + Result.BaseType = TypeSystem.CStruct(name=TypeName) Result.IsStruct = True return Result return CTypeInfo() diff --git a/lib/core/TypeSpec.py b/lib/core/TypeSpec.py index 1b28bf5..198f3dc 100644 --- a/lib/core/TypeSpec.py +++ b/lib/core/TypeSpec.py @@ -20,7 +20,7 @@ from typing import TYPE_CHECKING, List, Dict, Tuple, Any, Optional if TYPE_CHECKING: from lib.core.Handles.HandlesBase import CTypeInfo -from lib.includes import t +from lib.core import TypeSystem class SymbolKind(enum.Enum): @@ -135,14 +135,14 @@ class TypeSpec: ) def __init__(self): - self._base_type: t.CType | tuple | None = None # t.CType 实例或 tuple + self._base_type: TypeSystem.CType | tuple | None = None # CType 实例或 tuple self.ptr_count: int = 0 self.var_const: bool = False self.var_volatile: bool = False self.data_const: bool = False self.data_volatile: bool = False self.array_dims: List[str] = [] - self.storage: t.CType | None = None # t.CType (CStatic/CExtern/CExport 等) + self.storage: TypeSystem.CType | None = None # CType (CStatic/CExtern/CExport 等) self.is_func_ptr: bool = False self.func_ptr_params: List[Tuple[str, CTypeInfo]] = [] # (参数名, CTypeInfo) self.func_param_names: List[str] = [] @@ -158,11 +158,11 @@ class TypeSpec: self.is_signed: Optional[bool] = None # None = 未设置, True/False = 有符号/无符号 @property - def base_type(self) -> t.CType | tuple | None: + def base_type(self) -> TypeSystem.CType | tuple | None: return self._base_type @base_type.setter - def base_type(self, value: t.CType | tuple | None): + def base_type(self, value: TypeSystem.CType | tuple | None): """设置 BaseType,与 CTypeInfo.BaseType setter 逻辑一致(不含 kind 副作用)""" if value is None: self._base_type = None @@ -172,16 +172,16 @@ class TypeSpec: self._base_type = tuple(value) return - if isinstance(value, type) and issubclass(value, t.CType): + if isinstance(value, type) and issubclass(value, TypeSystem.CType): self._base_type = value() return - if isinstance(value, t.CType): + if isinstance(value, TypeSystem.CType): self._base_type = value return raise TypeError( - f"base_type must be t.CType instance, type subclass, or tuple of t.CType, got {type(value)}" + f"base_type must be CType instance, type subclass, or tuple of CType, got {type(value)}" ) def copy(self) -> TypeSpec: diff --git a/lib/includes/t.py b/lib/core/TypeSystem.py similarity index 82% rename from lib/includes/t.py rename to lib/core/TypeSystem.py index 69afa18..4bac177 100644 --- a/lib/includes/t.py +++ b/lib/core/TypeSystem.py @@ -1,13 +1,14 @@ -# 类型定义模块 +"""TPC 内建类型模型。 + +源码注解只使用内建类型名(`CPtr`、`CInt`、`CArray` 等);本模块是这些名字在 +编译器内部的唯一表示,包含类型元属性、平台位宽和类型注册表。 +""" from __future__ import annotations import sys import types from typing import Any, ClassVar, Optional, TypeVar, Generic, TypeAlias, Callable -from lib.constants.config import mode as _ConfigMode -from lib.core.VLogger import get_logger as _vlog - # ============================================================================= # 类型映射常量 @@ -129,7 +130,7 @@ class CType: return [self, other] def __set_default__(self, **kwargs: Any) -> CTypeDefault: - """设置默认值/初始值,用于 static/global 变量的初始化 + """设置默认值/初始值,用于 static/global 变量的初始化。 Args: **kwargs: 成员名称和值的键值对 @@ -342,7 +343,7 @@ def CVTable() -> None: def NoVTable() -> None: """标记类为非多态继承基类:被子类继承时字段直接展平嵌入,不生成 vtable,避免 vtable 开销。 - 区别于 @t.CVTable(启用多态 vtable)。对应 C++ 的非多态继承(struct A : B {} 无 virtual)。""" + 区别于 @CVTable(启用多态 vtable)。对应 C++ 的非多态继承(struct A : B {} 无 virtual)。""" pass def TLS() -> None: @@ -467,6 +468,118 @@ class CUInt64T(CType): self.IsSigned: bool = False self.Size: int = 64 +class CIntFast8T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 8 + +class CIntFast16T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 16 + +class CIntFast32T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 32 + +class CIntFast64T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 64 + +class CUIntFast8T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 8 + +class CUIntFast16T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 16 + +class CUIntFast32T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 32 + +class CUIntFast64T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 64 + +class CIntLeast8T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 8 + +class CIntLeast16T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 16 + +class CIntLeast32T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 32 + +class CIntLeast64T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = True + self.Size: int = 64 + +class CUIntLeast8T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 8 + +class CUIntLeast16T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 16 + +class CUIntLeast32T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 32 + +class CUIntLeast64T(CType): + position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) + def __init__(self, value: Any = None) -> None: + super().__init__(value) + self.IsSigned: bool = False + self.Size: int = 64 + class CIntPtrT(CType): position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: @@ -540,9 +653,9 @@ class CAutoPtr(CPtr): super().__init__(value) class CTypeDefault(CType): - """用于存储 C 类型默认值/初始化的包装类 + """用于存储 C 类型默认值/初始化的包装类。 - 当使用 t.CStatic.__set_default__(open=mouse_open, ...) 时创建 + 当使用 CStatic.__set_default__(open=mouse_open, ...) 时创建。 """ def __init__(self, BaseType: Any, **kwargs: Any) -> None: super().__init__() @@ -560,8 +673,9 @@ class CArrayPtr(CType): class CArray(CType): """栈上固定数组类型注解。 - 用法: names: t.CArray[VOIDPTR, 32] # void*[32] - data: t.CArray[t.CInt, 64] # int[64] + + 用法: names: CArray[rawptr, 32] # void*[32] + data: CArray[int, 64] # int[64] 第一个参数为元素类型,第二个参数为数组大小(整数或常量名)。""" position: ClassVar[frozenset[str]] = frozenset({CType.ARRAY}) def __init__(self, value: Any = None) -> None: @@ -570,13 +684,11 @@ class CArray(CType): return cls class CDefine(CType): - """编译期常量定义标记(X: t.CDefine = 64)。 + """编译期常量定义标记(`X: CDefine = 64`)。 - Size/IsSigned 覆盖为 32 位有符号整数(2026-08-10 修复):基类 __init__ - 将 Size/IsSigned 置 None,导致 CTypeToLLVM(CDefine) 推导为 'void', - 类字段注解 t.CDefine(如 Mixin 的常量声明)在 stub 生成时变成 void, - LLVM struct 含 void 报 "void type only allowed for function results"。 - 语义上 CDefine 常量即为 int;超大值由 TypeConvert 按 DefineValue 升 i64。 + Size/IsSigned 固定为 32 位有符号整数:基类会把两者置 None,推导结果为 + `void`,使类字段注解在结构体中生成非法 void 成员。语义上 CDefine 常量 + 即为 int;超大值由 TypeConvert 按 DefineValue 升 i64。 """ position: ClassVar[frozenset[str]] = frozenset({CType.BASE}) def __init__(self, value: Any = None) -> None: @@ -595,8 +707,8 @@ class State(CType): @staticmethod def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 t.State() 调用""" - return ['t.State'] + """处理 State() 调用""" + return ['State'] class Postdefinition: def __init__(self, c: Any) -> None: @@ -614,7 +726,7 @@ class BigEndian(CType): 用法示例: class MyStruct: - a: t.CInt | t.BigEndian # 大端序存储的整数 + a: CInt | BigEndian # 大端序存储的整数 """ IsSigned: ClassVar[bool] = True Size: ClassVar[int] = 32 @@ -628,7 +740,7 @@ class LittleEndian(CType): 用法示例: class MyStruct: - b: t.CInt | t.LittleEndian # 小端序存储的整数 + b: CInt | LittleEndian # 小端序存储的整数 """ IsSigned: ClassVar[bool] = True Size: ClassVar[int] = 32 @@ -991,7 +1103,7 @@ class attr: """LLVM 函数属性描述符 用于在返回类型注解中指定 LLVM 函数属性。 - 例如: def foo() -> t.CInt | t.attr.llvm.nobuiltin | t.attr.llvm.nounwind: + 例如: def foo() -> CInt | attr.llvm.nobuiltin | attr.llvm.nounwind: """ # 以下空类仅作为类型注解占位符使用,由 HandlesFunctions._GetAttrLLVMName @@ -1011,13 +1123,34 @@ class attr: class inaccessiblemem_or_argmemonly: pass +# 内建类型的源码书写名:这些名字由编译器直接识别,不依赖任何导入或 typedef。 +BUILTIN_TYPE_ALIASES: dict[str, type] = { + 'sizet': CSizeT, 'size_t': CSizeT, + 'int8': CInt8T, 'int16': CInt16T, 'int32': CInt32T, 'int64': CInt64T, + 'uint8': CUInt8T, 'uint16': CUInt16T, 'uint32': CUInt32T, 'uint64': CUInt64T, + 'intfast8': CIntFast8T, 'intfast16': CIntFast16T, + 'intfast32': CIntFast32T, 'intfast64': CIntFast64T, + 'uintfast8': CUIntFast8T, 'uintfast16': CUIntFast16T, + 'uintfast32': CUIntFast32T, 'uintfast64': CUIntFast64T, + 'intleast8': CIntLeast8T, 'intleast16': CIntLeast16T, + 'intleast32': CIntLeast32T, 'intleast64': CIntLeast64T, + 'uintleast8': CUIntLeast8T, 'uintleast16': CUIntLeast16T, + 'uintleast32': CUIntLeast32T, 'uintleast64': CUIntLeast64T, + 'uchar': CUnsignedChar, + 'short': CInt16T, 'ushort': CUInt16T, 'uint': CUnsignedInt, + 'long': CInt32T, 'ulong': CUInt32T, + 'longlong': CInt64T, 'ulonglong': CUInt64T, + 'ptrdifft': CPtrDiffT, +} + + class CTypeRegistry: """基于 CType 元属性的类型注册表,替代手动映射表 利用 CType 子类的 position/IsSigned/Size 元属性自动推导: - LLVM IR 类型字符串 (如 'i32', 'double', 'i8*') - C 类型名称 (如 'int', 'unsigned char', 'long long') - - Python CType 类引用 (如 t.CInt32T) + - Python CType 类引用 (如 CInt32T) """ _name_to_class: ClassVar[Optional[dict[str, type]]] = None @@ -1052,7 +1185,7 @@ class CTypeRegistry: @classmethod def GetClassByName(cls, name: str) -> Optional[type]: - """根据 Python 类名获取 CType 类 (如 'CInt32T' -> t.CInt32T)""" + """根据 Python 类名获取 CType 类 (如 'CInt32T' -> CInt32T)""" cls._build() return cls._name_to_class.get(name) @@ -1114,6 +1247,9 @@ class CTypeRegistry: 未知类型返回 None。 """ cls._build() + alias: Optional[type] = BUILTIN_TYPE_ALIASES.get(name) + if alias is not None: + return cls.CTypeToLLVM(alias) mod: Optional[types.ModuleType] = sys.modules.get(__name__) if mod and hasattr(mod, name): obj: Any = getattr(mod, name) @@ -1126,17 +1262,22 @@ class CTypeRegistry: """解析类型名到 (CType类, 指针层级) 支持的格式: - - Python 类名: 'CInt32T' -> (t.CInt32T, 0) - - C 基本类型名/Python 内置名: 'int' -> (t.CInt, 0), 'bool' -> (t.CBool, 0) + - Python 类名: 'CInt32T' -> (CInt32T, 0) + - C 基本类型名/Python 内置名: 'int' -> (CInt, 0), 'bool' -> (CBool, 0) 注意:stdint.h 类型名(int8_t/uint8_t/size_t/intptr_t 等)和 Win32 大写别名(INT8/UINT8/BYTE/DWORD/FLOAT8 等)由 stdint.py - 通过 t.CTypedef 提供,用户 `from stdint import *` 后即可使用。 + 通过 CTypedef 提供,用户 `from stdint import *` 后即可使用。 - 指针必须使用 t.CPtr[T] 显式表达(如 t.CPtr[t.CInt]), + 指针必须使用 CPtr[T] 显式表达(如 CPtr[CInt]), 本方法不再做 PTR 后缀的隐式类型推断,以避免违反类型自由原则。 """ cls._build() + alias: Optional[type] = BUILTIN_TYPE_ALIASES.get(name) + if alias is not None: + pos: frozenset[str] = getattr(alias, 'position', frozenset()) + ptr_level: int = 1 if CType.POINTER in pos and CType.BASE not in pos else 0 + return (alias, ptr_level) direct: Optional[type] = cls._name_to_class.get(name) if direct is not None: pos: frozenset[str] = getattr(direct, 'position', frozenset()) diff --git a/lib/core/stub_generator.py b/lib/core/stub_generator.py index d4becba..c4debbb 100644 --- a/lib/core/stub_generator.py +++ b/lib/core/stub_generator.py @@ -48,40 +48,40 @@ class CTypeMapper: # 不再依赖运行时 CTypeRegistry._cname_to_class(该映射已删除)。 _CNAME_TO_PY: dict[str, str] = { # 基本类型 - 'char': 't.CChar', 'int': 't.CInt', 'short': 't.CShort', - 'long': 't.CLong', 'long long': 't.CLongLong', - 'float': 't.CFloat', 'double': 't.CDouble', 'void': 't.CVoid', + 'char': 'CChar', 'int': 'CInt', 'short': 'CShort', + 'long': 'CLong', 'long long': 'CLongLong', + 'float': 'CFloat', 'double': 'CDouble', 'void': 'CVoid', # unsigned / signed 变体 - 'unsigned': 't.CUnsigned', 'unsigned char': 't.CUnsignedChar', - 'unsigned int': 't.CUnsignedInt', 'unsigned short': 't.CUnsignedShort', - 'unsigned long': 't.CUnsignedLong', - 'unsigned long long': 't.CUnsignedLongLong', - 'signed char': 't.CSignedChar', + 'unsigned': 'CUnsigned', 'unsigned char': 'CUnsignedChar', + 'unsigned int': 'CUnsignedInt', 'unsigned short': 'CUnsignedShort', + 'unsigned long': 'CUnsignedLong', + 'unsigned long long': 'CUnsignedLongLong', + 'signed char': 'CSignedChar', # bool / size_t - 'bool': 't.CBool', '_Bool': 't.CBool', 'size_t': 't.CSizeT', - 'ssize_t': 't.CLong', + 'bool': 'CBool', '_Bool': 'CBool', 'size_t': 'CSizeT', + 'ssize_t': 'CLong', # stdint 固定宽度类型 - 'int8_t': 't.CInt8T', 'int16_t': 't.CInt16T', - 'int32_t': 't.CInt32T', 'int64_t': 't.CInt64T', - 'uint8_t': 't.CUInt8T', 'uint16_t': 't.CUInt16T', - 'uint32_t': 't.CUInt32T', 'uint64_t': 't.CUInt64T', - 'intptr_t': 't.CIntPtrT', 'uintptr_t': 't.CUIntPtrT', - 'ptrdiff_t': 't.CPtrDiffT', + 'int8_t': 'CInt8T', 'int16_t': 'CInt16T', + 'int32_t': 'CInt32T', 'int64_t': 'CInt64T', + 'uint8_t': 'CUInt8T', 'uint16_t': 'CUInt16T', + 'uint32_t': 'CUInt32T', 'uint64_t': 'CUInt64T', + 'intptr_t': 'CIntPtrT', 'uintptr_t': 'CUIntPtrT', + 'ptrdiff_t': 'CPtrDiffT', # 宽字符 / 字符类型 - 'wchar_t': 't.CWCharT', 'char8_t': 't.CChar8T', - 'char16_t': 't.CChar16T', 'char32_t': 't.CChar32T', + 'wchar_t': 'CWCharT', 'char8_t': 'CChar8T', + 'char16_t': 'CChar16T', 'char32_t': 'CChar32T', # 浮点特化类型 - 'float8_t': 't.CFloat8T', 'float16_t': 't.CFloat16T', - 'float32_t': 't.CFloat32T', 'float64_t': 't.CFloat64T', - 'float128_t': 't.CFloat128T', + 'float8_t': 'CFloat8T', 'float16_t': 'CFloat16T', + 'float32_t': 'CFloat32T', 'float64_t': 'CFloat64T', + 'float128_t': 'CFloat128T', # signed 速记 - 'signed': 't.CInt', 'signed int': 't.CInt', - 'signed short': 't.CShort', 'signed long': 't.CLong', + 'signed': 'CInt', 'signed int': 'CInt', + 'signed short': 'CShort', 'signed long': 'CLong', } @classmethod def _ResolveCNameToPyType(cls, c_type: str) -> str: - """将 C 类型名解析为 Python 类型字符串(如 'int' → 't.CInt') + """将 C 类型名解析为 Python 类型字符串(如 'int' → 'CInt') 使用硬编码映射表,不再依赖 CTypeRegistry._cname_to_class。 未识别的类型原样返回(用于 struct/union/enum/typedef 用户自定义名)。 @@ -110,7 +110,7 @@ class CTypeMapper: PtrSuffix: str = '' if IsPtr or c_type.endswith('*'): - PtrSuffix = ' | t.CPtr' + PtrSuffix = ' | CPtr' c_type = c_type.rstrip('*').strip() if c_type.startswith('struct '): @@ -125,7 +125,7 @@ class CTypeMapper: result: str = PyType + PtrSuffix if IsArray: - result += ' | t.CArrayPtr' + result += ' | CArrayPtr' return result @@ -603,7 +603,7 @@ class PythonStubGenerator: def generate(self, ModuleName: str | None = None) -> str: self.OutputLines = [] self._AddHeader(ModuleName) - self._GenerateImports() + # stub 头部只放模块文档;内建标记按裸名使用,无需 import。 self._GenerateDefines() self._GenerateFuncPtrTypedefs() self._GenerateSimpleTypedefs() @@ -622,11 +622,6 @@ class PythonStubGenerator: self.OutputLines.append('"""') self.OutputLines.append('') - def _GenerateImports(self) -> None: - self.OutputLines.append('import t') - self.OutputLines.append('import c') - self.OutputLines.append('') - def _GenerateDefines(self) -> None: if not self.parser.defines: return @@ -634,9 +629,9 @@ class PythonStubGenerator: Name: str = define['name'] Value: str | None = define['value'] if Value is not None: - self.OutputLines.append(f'{Name}: t.CDefine = {Value}') + self.OutputLines.append(f'{Name}: CDefine = {Value}') else: - self.OutputLines.append(f'{Name}: t.CDefine') + self.OutputLines.append(f'{Name}: CDefine') self.OutputLines.append('') def _GenerateFuncPtrTypedefs(self) -> None: @@ -648,7 +643,7 @@ class PythonStubGenerator: for p in Info['params']: ParamTypes.append(CTypeMapper.MapType(p['type'])) ParamStr: str = ', '.join(ParamTypes) if ParamTypes else '' - self.OutputLines.append(f'{Name}: t.CTypedef = t.Callable[[{ParamStr}], {RetType}]') + self.OutputLines.append(f'{Name}: CTypedef = Callable[[{ParamStr}], {RetType}]') self.OutputLines.append('') def _GenerateSimpleTypedefs(self) -> None: @@ -658,15 +653,15 @@ class PythonStubGenerator: AliasName: str = td['name'] BaseType: str = td['base'] PyType: str = CTypeMapper.MapType(BaseType) - self.OutputLines.append(f'{AliasName}: t.CTypedef | {PyType}') + self.OutputLines.append(f'{AliasName}: CTypedef | {PyType}') self.OutputLines.append('') def _GenerateStructs(self) -> None: if not self.parser.structs: return for StructName, StructInfo in self.parser.structs.items(): - self.OutputLines.append(f'@c.Attribute(t.attr.packed)') - self.OutputLines.append(f'class {StructName}(t.CStruct):') + self.OutputLines.append(f'@Attribute(attr.packed)') + self.OutputLines.append(f'class {StructName}(CStruct):') if StructInfo['members']: for member in StructInfo['members']: MemberName: str = member['name'] @@ -677,7 +672,7 @@ class PythonStubGenerator: if IsArray and ArraySize is not None: self.OutputLines.append(f' {MemberName}: list[{PyType}, {ArraySize}]') elif IsArray: - self.OutputLines.append(f' {MemberName}: {PyType} | t.CArrayPtr') + self.OutputLines.append(f' {MemberName}: {PyType} | CArrayPtr') else: self.OutputLines.append(f' {MemberName}: {PyType}') else: @@ -688,8 +683,8 @@ class PythonStubGenerator: if not self.parser.unions: return for UnionName, UnionInfo in self.parser.unions.items(): - self.OutputLines.append(f'@c.Attribute(t.attr.packed)') - self.OutputLines.append(f'class {UnionName}(t.CUnion):') + self.OutputLines.append(f'@Attribute(attr.packed)') + self.OutputLines.append(f'class {UnionName}(CUnion):') if UnionInfo['members']: for member in UnionInfo['members']: PyType: str = CTypeMapper.MapType(member['type'], IsPtr=member.get('IsPtr', False)) @@ -702,16 +697,16 @@ class PythonStubGenerator: if not self.parser.enums: return for EnumName, EnumInfo in self.parser.enums.items(): - self.OutputLines.append(f'class __{EnumName.lower()}(t.CEnum):') + self.OutputLines.append(f'class __{EnumName.lower()}(CEnum):') if EnumInfo['values']: for value in EnumInfo['values']: if value['value'] is not None: - self.OutputLines.append(f' {value["name"]}: t.CDefine = {value["value"]}') + self.OutputLines.append(f' {value["name"]}: CDefine = {value["value"]}') else: - self.OutputLines.append(f' {value["name"]}: t.CDefine') + self.OutputLines.append(f' {value["name"]}: CDefine') else: self.OutputLines.append(' pass') - self.OutputLines.append(f'{EnumName}: t.CTypedef = __{EnumName.lower()}') + self.OutputLines.append(f'{EnumName}: CTypedef = __{EnumName.lower()}') self.OutputLines.append('') def _GenerateVariables(self) -> None: diff --git a/lib/includes/__init__.py b/lib/includes/__init__.py deleted file mode 100644 index 6129c5d..0000000 --- a/lib/includes/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""类型系统与 C 语法定义 (t.py / c.py)""" diff --git a/lib/includes/c.py b/lib/includes/c.py deleted file mode 100644 index bb2b46f..0000000 --- a/lib/includes/c.py +++ /dev/null @@ -1,634 +0,0 @@ -# C语法定义模块 -from __future__ import annotations - -import vast as ast -import logging -from typing import Any, Optional - -from . import t -from lib.constants.config import mode as _config_mode - -def _to_str(node: Any) -> str: - if node is None: - return '' - if isinstance(node, str): - return node - if isinstance(node, list): - return ' && '.join([_to_str(n) for n in node]) - NodeType: str = type(node).__name__ - if NodeType == 'Constant': - return node.value - elif NodeType == 'ID': - return node.name - elif NodeType == 'BinaryOp': - left: str = _to_str(node.left) - right: str = _to_str(node.right) - return f'{left} {node.op} {right}' - elif NodeType == 'UnaryOp': - expr: str = _to_str(node.expr) - return f'{node.op}{expr}' - else: - return repr(node) - -class Asm: - @staticmethod - def _parse_asm_descr(expr: ast.AST) -> str: - """递归解析AST节点,确保获取t.ASM_DESCR的实际值,支持|组合 - 处理场景: - 1. t.ASM_DESCR.XXX → 取属性值 - 2. t.ASM_DESCR.XXX | t.ASM_DESCR.YYY → 拼接两个值 - 3. 常量字符串 → 直接返回 - """ - # 场景1:位或组合(XXX | YYY) - if isinstance(expr, ast.BinOp): - left_val: str = Asm._parse_asm_descr(expr.left) - right_val: str = Asm._parse_asm_descr(expr.right) - return left_val + right_val - - # 场景2:t.ASM_DESCR.XXX 多层属性访问 - elif isinstance(expr, ast.Attribute): - # 第一步:判断是否是 t.ASM_DESCR 的属性 - if isinstance(expr.value, ast.Attribute): - # 内层是 t.ASM_DESCR - if (isinstance(expr.value.value, ast.Name) and - expr.value.value.id == 't' and - expr.value.attr == 'ASM_DESCR'): - # 取 t.ASM_DESCR.XXX 的实际值 - AttrName: str = expr.attr - if hasattr(t.ASM_DESCR, AttrName): - return getattr(t.ASM_DESCR, AttrName, "") - - # 兼容 t.XXX 简化写法(如果有的话) - elif isinstance(expr.value, ast.Name) and expr.value.id == 't': - AttrName: str = expr.attr - if hasattr(t.ASM_DESCR, AttrName): - return getattr(t.ASM_DESCR, AttrName, "") - - # 场景3:直接传常量(如 "r"、"cc") - elif isinstance(expr, ast.Constant): - return expr.value - - # 其他场景返回空 - return "" - - @staticmethod - def _extract_val_expr(translator: Any, expr_node: ast.AST) -> str: - """从AST表达式节点提取值表达式的字符串形式""" - val_ExprNode: Any = translator.HandleExpr(expr_node)[0] - if isinstance(val_ExprNode, str): - return val_ExprNode - try: - return str(val_ExprNode) - except Exception as _e: - if _config_mode == "strict": - logging.warning(f"异常被忽略: {_e}") - return '' - - @staticmethod - def _parse_asm_template(translator: Any, args: list[ast.AST]) -> tuple[str, list[tuple[str, str]], list[tuple[str, str]], int]: - """解析f-string或常量模板字符串,返回(asm_code, output_ops, input_ops, operand_seq)""" - output_ops: list[tuple[str, str]] = [] - input_ops: list[tuple[str, str]] = [] - operand_seq: int = 0 - asm_code: str = "" - first_arg: ast.AST = args[0] - - if isinstance(first_arg, ast.JoinedStr): - asm_parts: list[str] = [] - for part in first_arg.values: - if isinstance(part, ast.Constant): - asm_parts.append(part.value) - elif isinstance(part, ast.FormattedValue): - expr: ast.AST = part.value - if isinstance(expr, ast.Call) and isinstance(expr.func, ast.Attribute) and expr.func.value.id == 'c': - # 解析内联的AsmInp/AsmOut - call_node: ast.Call = expr - val_expr: str = Asm._extract_val_expr(translator, call_node.args[0]) if len(call_node.args)>=1 else "" - constraint: str = Asm._parse_asm_descr(call_node.args[1]) if len(call_node.args)>=2 else "" - - if call_node.func.attr == 'AsmOut': - output_ops.append((val_expr, constraint)) - asm_parts.append(f"%{operand_seq}") - operand_seq += 1 - elif call_node.func.attr == 'AsmInp': - input_ops.append((val_expr, constraint)) - asm_parts.append(f"%{operand_seq}") - operand_seq += 1 - else: - asm_parts.append(translator.HandleExpr(expr)[0]) - asm_code = ''.join(asm_parts) - elif isinstance(first_arg, ast.Constant): - asm_code = first_arg.value - - return asm_code, output_ops, input_ops, operand_seq - - @staticmethod - def _parse_asm_operands(translator: Any, args: list[ast.AST], keywords: list[ast.keyword], output_ops: list[tuple[str, str]], input_ops: list[tuple[str, str]], operand_seq: int) -> tuple[list[tuple[str, str]], list[tuple[str, str]], int]: - """解析位置参数和关键字参数中的输出/输入操作数""" - - def parse_operand(arg: ast.AST) -> Optional[tuple[str, str, str]]: - """解析 AsmInp/AsmOut 参数""" - if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Attribute) and arg.func.value.id == 'c': - call_node: ast.Call = arg - val_expr: str = Asm._extract_val_expr(translator, call_node.args[0]) if len(call_node.args)>=1 else "" - constraint: str = Asm._parse_asm_descr(call_node.args[1]) if len(call_node.args)>=2 else "" - - if call_node.func.attr == 'AsmOut': - return ('out', val_expr, constraint) - elif call_node.func.attr == 'AsmInp': - return ('in', val_expr, constraint) - return None - - # 处理位置参数中的操作数 - for arg in args[1:]: - result: Optional[tuple[str, str, str]] = parse_operand(arg) - if result: - direction, val_expr, constraint = result - if direction == 'out': - output_ops.append((val_expr, constraint)) - operand_seq += 1 - elif direction == 'in': - input_ops.append((val_expr, constraint)) - operand_seq += 1 - - # 处理关键字参数中的操作数 - for kw in keywords: - if kw.arg == 'out': - # 处理 out 关键字参数 (输出操作数) - if isinstance(kw.value, ast.List): - for elt in kw.value.elts: - result = parse_operand(elt) - if result and result[0] == 'out': - output_ops.append((result[1], result[2])) - operand_seq += 1 - elif isinstance(kw.value, ast.Call): - result = parse_operand(kw.value) - if result and result[0] == 'out': - output_ops.append((result[1], result[2])) - operand_seq += 1 - elif kw.arg == 'inp' or kw.arg == 'inputs': - # 处理 inp/inputs 关键字参数 (输入操作数,追加到f-string中已有输入之后) - if isinstance(kw.value, ast.List): - for elt in kw.value.elts: - if isinstance(elt, ast.Tuple): - # 处理列表中的 (value, constraint) 元组格式 - if len(elt.elts) >= 2: - val_expr: str = Asm._extract_val_expr(translator, elt.elts[0]) if len(elt.elts) >= 1 else "" - constraint: str = Asm._parse_asm_descr(elt.elts[1]) - input_ops.append((val_expr, constraint)) - operand_seq += 1 - else: - result = parse_operand(elt) - if result and result[0] == 'in': - input_ops.append((result[1], result[2])) - operand_seq += 1 - elif isinstance(kw.value, ast.Call): - result = parse_operand(kw.value) - if result and result[0] == 'in': - input_ops.append((result[1], result[2])) - operand_seq += 1 - elif isinstance(kw.value, ast.Tuple): - # 处理 (value, constraint) 元组格式 - if len(kw.value.elts) >= 2: - val_expr: str = Asm._extract_val_expr(translator, kw.value.elts[0]) if len(kw.value.elts) >= 1 else "" - constraint: str = Asm._parse_asm_descr(kw.value.elts[1]) - input_ops.append((val_expr, constraint)) - operand_seq += 1 - - return output_ops, input_ops, operand_seq - - @staticmethod - def _parse_asm_clobbers(args: list[ast.AST], keywords: list[ast.keyword]) -> list[str]: - """解析位置参数和关键字参数中的破坏列表""" - clobbers: list[str] = [] - - # 处理位置参数中的破坏列表 - for arg in args[1:]: - if isinstance(arg, ast.List): - # 解析破坏列表(支持|组合) - for elt in arg.elts: - clobber_val: str = Asm._parse_asm_descr(elt) - if clobber_val: - clobbers.append(clobber_val) - - # 处理关键字参数中的破坏列表 - for kw in keywords: - if kw.arg == 'op': - # 处理 op 关键字参数 (clobber,破坏列表) - if isinstance(kw.value, ast.List): - for elt in kw.value.elts: - clobber_val: str = Asm._parse_asm_descr(elt) - if clobber_val: - clobbers.append(clobber_val) - elif kw.arg == 'clobber': - # 处理 clobber 关键字参数 - if isinstance(kw.value, ast.List): - for elt in kw.value.elts: - clobber_val: str = Asm._parse_asm_descr(elt) - if clobber_val: - clobbers.append(clobber_val) - - return clobbers - - @staticmethod - def _generate_asm_code(asm_code: str, output_ops: list[tuple[str, str]], input_ops: list[tuple[str, str]], clobbers: list[str], asm_format: str) -> list[str]: - """格式化汇编代码并生成最终的__asm__代码字符串""" - # 格式化汇编代码 - asm_lines: list[str] = [line.strip() for line in asm_code.split('\n') if line.strip()] - formatted_asm: str = '\n '.join([f'"{line}\\n"' for line in asm_lines]) - - # 拼接约束字符串 - # 输出约束:如果约束已包含 = 或 +,直接使用;否则添加 = - def format_constraint(constraint: str, is_output: bool = True) -> str: - if not constraint: - return "" - # 如果约束已包含修饰符,直接返回 - if '=' in constraint or '+' in constraint: - return constraint - # 否则添加适当的修饰符 - return ('=' if is_output else '') + constraint - - out_const: str = ', '.join([f'"{format_constraint(c, True)}"({v})' for v, c in output_ops]) if output_ops else "" - in_const: str = ', '.join([f'"{format_constraint(c, False)}"({v})' for v, c in input_ops]) if input_ops else "" - clobber_const: str = ', '.join([f'"{x}"' for x in clobbers]) if clobbers else "" - - # 构建约束部分:确保冒号格式正确 - constraint_parts: list[str] = [] - # 输出约束 - if output_ops: - constraint_parts.append(f': {out_const}') - elif input_ops or clobbers: - constraint_parts.append(':') - - # 输入约束 - if input_ops: - constraint_parts.append(f': {in_const}') - elif clobbers: - constraint_parts.append(':') - - # 破坏列表 - if clobbers: - constraint_parts.append(f': {clobber_const}') - - constraint_str: str = ' '.join(constraint_parts) - - # 生成最终代码 - if asm_format == 'ARM': - # ARM 使用 .arch 指令和不同的内联汇编语法 - final_asm: str = f'__asm__ __volatile__ (\n {formatted_asm} {constraint_str});' - elif asm_format == 'AT&T': - # AT&T 语法不需要额外标记,GCC 默认就是 AT&T - final_asm = f'__asm__ __volatile__ (\n {formatted_asm} {constraint_str});' - else: - # Intel 语法需要 .intel_syntax 指令 - final_asm = f'__asm__ __volatile__ (".intel_syntax noprefix\\n\\t"\n {formatted_asm} ".att_syntax prefix" {constraint_str});' - return [final_asm] - - @staticmethod - def HandleCall(translator: Any, args: list[ast.AST], keywords: list[ast.keyword]) -> list[str]: - if not args: - return ['__asm__ volatile ("nop");'] - - # 解析模板 - asm_code: str - output_ops: list[tuple[str, str]] - input_ops: list[tuple[str, str]] - operand_seq: int - asm_code, output_ops, input_ops, operand_seq = Asm._parse_asm_template(translator, args) - - # 解析操作数 - output_ops, input_ops, operand_seq = Asm._parse_asm_operands( - translator, args, keywords, output_ops, input_ops, operand_seq) - - # 解析破坏列表 - clobbers: list[str] = Asm._parse_asm_clobbers(args, keywords) - - # 解析汇编格式 - asm_format: str = 'Intel' - for kw in keywords: - if kw.arg == 'format': - if isinstance(kw.value, ast.Constant) and isinstance(kw.value.value, str): - asm_format = kw.value.value - - # 生成最终代码 - return Asm._generate_asm_code(asm_code, output_ops, input_ops, clobbers, asm_format) - -class AsmInp: - def __init__(self, value: Any, constraint: Any) -> None: - self.value: Any = value - self.constraint: Any = constraint - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]: - return [] - -class AsmOut: - def __init__(self, value: Any, constraint: Any) -> None: - self.value: Any = value - self.constraint: Any = constraint - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]: - return [] - -class NoBreak: - """ switch 分支无break """ - pass - -class Break: - """ switch 分支提前break """ - pass - -class Load: - """解引用a写入b,等价于 *b = *a,无拷贝副作用""" - def __init__(self, src: Any, dst: Any) -> None: - self.src: Any = src - self.dst: Any = dst - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - if len(args) >= 2: - src: Any = translator.HandleExpr(args[0])[0] - dst: Any = translator.HandleExpr(args[1])[0] - return [f'*({dst}) = *({src})'] - return [] - - -class Addr: - """取地址""" - def __init__(self, addr: Any) -> None: - self.addr: Any = addr - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.Addr() 调用""" - if args: - expr: Any = translator.HandleExpr(args[0])[0] - if isinstance(expr, str): - return [f'&{expr}'] - return [f'&{_to_str(expr)}'] - return ['0'] - - -class Deref: - """解引用""" - def __init__(self, ptr: Any) -> None: - self.ptr: Any = ptr - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.Deref() 调用""" - if args: - expr: Any = translator.HandleExpr(args[0])[0] - if hasattr(expr, 'op') and expr.op == '*': - return [expr] - return [f'*({_to_str(expr)})'] - return ['0'] - - -class DerefAs: - """解引用写入,等价于 *ptr = value""" - def __init__(self, ptr: Any, value: Any) -> None: - self.ptr: Any = ptr - self.value: Any = value - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.DerefAs() 调用""" - if len(args) >= 2: - ptr: Any = translator.HandleExpr(args[0])[0] - val: Any = translator.HandleExpr(args[1])[0] - return [f'*({_to_str(ptr)}) = {_to_str(val)}'] - return [] - - -class Set: - """设置值""" - def __init__(self, key: Any, value: Any) -> None: - self.key: Any = key - self.value: Any = value - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.Set() 调用""" - if len(args) >= 2: - target: Any = translator.HandleExpr(args[0])[0] - value: Any = translator.HandleExpr(args[1])[0] - return [f'{_to_str(target)} = {_to_str(value)}'] - return [] - - -class CReturn: - """【已移除】多返回值装饰器(墓碑)。 - - 该类已移除:源码中写 `@c.CReturn(...)` 会被编译器**报错**(fail-fast), - 不会静默忽略或改写。多返回值请改用返回注解 `-> tuple[ty1, ty2, ...]` - (返回多个值的函数打包为 struct 返回,调用处用元组解包接收)。 - """ - def __init__(self, *ReturnTypes: Any) -> None: - self.ReturnTypes: tuple[Any, ...] = ReturnTypes - - def __call__(self, func: Any) -> Any: - """装饰器调用""" - # 将返回类型信息附加到函数上 - func._CreturnTypes = self.ReturnTypes - return func - - -class CDefine: - """#define 宏定义""" - def __init__(self, name: Any, value: Any) -> None: - self.name: Any = name - self.value: Any = value - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.CDefine() 调用""" - if len(args) >= 1: - if isinstance(args[0], ast.Constant): - name: Any = args[0].value - else: - name = 'MACRO' - if len(args) >= 2: - value: Any = translator.HandleExpr(args[1])[0] - return ['#define ' + str(name) + ' ' + _to_str(value)] - return ['#define ' + str(name)] - return [] - - -class CError: - """#error 错误信息""" - def __init__(self, condition: Any) -> None: - self.condition: Any = condition - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.CError() 调用""" - if args: - # 如果是字符串常量,保留引号 - if isinstance(args[0], ast.Constant) and isinstance(args[0].value, str): - return ['#error "' + args[0].value + '"'] - else: - condition: Any = translator.HandleExpr(args[0])[0] - return ['#error ' + _to_str(condition)] - return ['#error "Error: Condition is not met."'] - - -class TokenPast: - """## 连接符""" - def __init__(self, left: Any, right: Any) -> None: - self.left: Any = left - self.right: Any = right - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]: - """处理 c.TokenPast() 调用""" - if len(args) >= 2: - # 处理左操作数 - 去掉引号 - if isinstance(args[0], ast.Constant): - left: str = str(args[0].value) - elif isinstance(args[0], ast.Name): - left = args[0].id - else: - left = _to_str(translator.HandleExpr(args[0])[0]) - - # 处理右操作数 - 去掉引号 - if isinstance(args[1], ast.Constant): - right: str = str(args[1].value) - elif isinstance(args[1], ast.Name): - right = args[1].id - else: - right = _to_str(translator.HandleExpr(args[1])[0]) - - # 返回字符串,但用特殊标记包装,让 _AstNodeToStr 能正确处理 - result: str = left + ' ## ' + right - # 使用一个特殊的类来包装结果,让 _AstNodeToStr 直接返回其值 - class TokenPastResult: - def __init__(self, value: str) -> None: - self.value: str = value - def __str__(self) -> str: - return self.value - return [TokenPastResult(result)] - return [''] - - -class CUndef: - """#undef 取消宏定义""" - def __init__(self, name: Any) -> None: - self.name: Any = name - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.CUndef(name) 调用""" - if args: - arg: Any = args[0] - if isinstance(arg, str): - name: str = arg - elif isinstance(arg, ast.Name): - name = arg.id - elif isinstance(arg, ast.Constant): - name = str(arg.value) - else: - name = str(arg) - return [f'#undef {name}'] - return ['#undef'] - - -class LLVMIR: - """内联 LLVM IR(无返回值,直接嵌入原始 IR 文本) - - 用法: c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}") - 或: c.LLVMIR(f"{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}") - - c.LInp(expr) - 输入操作数,替换为 expr 的 LLVM 值引用文本(%x 或常量) - c.LOut(expr) - 输出操作数:为 expr 变量分配唯一 SSA 寄存器 %llvmirN, - 模板嵌入后自动追加 store 写回变量 alloca - """ - def __init__(self, ir_template: Any, ret_type: Any = None) -> None: - self.ir_template: Any = ir_template - self.ret_type: Any = ret_type - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - return ['/* LLVMIR */'] - - -class LInp: - """LLVM IR 输入操作数标记 - - 用法: c.LInp(expr) - 标记 expr 为输入操作数 - 在 c.LLVMIR 的 f-string 中使用,翻译后替换为 %N 形式的操作数引用 - """ - def __init__(self, value: Any) -> None: - self.value: Any = value - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]: - return [] - - -class LOut: - """LLVM IR 输出操作数标记 - - 用法: c.LOut(expr) - 标记 expr 为输出操作数 - 在 c.LLVMIR 的 f-string 中使用,翻译后替换为 %N 形式的操作数引用 - """ - def __init__(self, value: Any) -> None: - self.value: Any = value - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]: - return [] - - -class CPragma: - """#pragma 指令 - - 用于生成 C 语言的 #pragma 指令。 - 例如:c.CPragma("GCC diagnostic push") 生成 #pragma GCC diagnostic push - """ - def __init__(self, directive: Any) -> None: - self.directive: Any = directive - - @staticmethod - def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]: - """处理 c.CPragma() 调用""" - if args: - arg: Any = args[0] - if isinstance(arg, ast.Constant): - directive: Any = arg.value - else: - expr: Any = translator.HandleExpr(arg)[0] - directive = _to_str(expr) - return [f'#pragma {directive}'] - return ['#pragma'] - - -# C 库类字典,用于 HandleCSpecialCall -Library_C = { - 'Asm': Asm, - 'Load': Load, - 'Addr': Addr, - 'Deref': Deref, - 'Set': Set, - 'AsmInp': AsmInp, - 'AsmOut': AsmOut, - 'CDefine': CDefine, - 'CUndef': CUndef, - 'CError': CError, - 'TokenPast': TokenPast, - 'CReturn': CReturn, - 'CPragma': CPragma, - 'LLVMIR': LLVMIR, - 'LInp': LInp, - 'LOut': LOut, -} - - -class Attribute: - """函数/变量属性装饰器""" - def __init__(self, *attrs: Any) -> None: - self.attrs: tuple[Any, ...] = attrs - - def __call__(self, func: Any) -> Any: - # 将属性附加到函数上 - func._c_attributes = self.attrs - return func diff --git a/lib/vast/ExprParser.py b/lib/vast/ExprParser.py index 76fe26c..c293f4c 100644 --- a/lib/vast/ExprParser.py +++ b/lib/vast/ExprParser.py @@ -69,7 +69,7 @@ _HEX_ALPHABET: str = '0123456789abcdefABCDEF' #(内部标记 c.@CIf 族由解析期合成,不走此处)。 _REMOVED_CIF_NAMES: frozenset[str] = frozenset({ 'CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif', - 'c.CIf', 'c.CIfdef', 'c.CIfndef', 'c.CElif', 'c.CElse', 'c.CEndif', + 'CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif', }) @@ -110,9 +110,9 @@ class TokenStream: self._PeekCacheIdx: int = -1 self._PeekCacheTok: Token | None = None # 类型注解解析模式:为 True 时 '*' / '**' 按 C 风格指针后缀处理 - # (int* → int | t.CPtr、int** → 嵌套两层),不按乘法/幂运算消费。 + # (int* → int | CPtr、int** → 嵌套两层),不按乘法/幂运算消费。 self._InTypeAnnotation: bool = False - # 下标实参嵌套层数:'[' 实参内是表达式位置(t.CArray[T, A * B] 的尺寸), + # 下标实参嵌套层数:'[' 实参内是表达式位置(CArray[T, A * B] 的尺寸), # 此处的 '*' 在有右操作数时按乘法解析(见 _ParseTerm / _AtOperandAfterStarRun)。 self._SubscriptArgs: int = 0 # Tail token of the last consumed C-style pointer suffix ('*' / '**'). @@ -463,13 +463,13 @@ class ExprParserMixin(TokenStream): op_type: type | None = None if tok.Type == OP: if tok.Value == '*' and self._AtPtrSuffix(left): - # C 风格指针后缀('*' 一层);展开为 base | t.CPtr 后继续。 + # C 风格指针后缀('*' 一层);展开为 base | CPtr 后继续。 left = self._ConsumePtrSuffix(left) continue if self._InTypeAnnotation and tok.Value == '*': # 注解模式:'*' 后已无操作数(']' / ',' / ')' / ':' / '=' / 行尾 / ';') # 时它是 C 风格指针后缀标记,交上方判据与 _ParseTypeAnnotation 统一消费; - # 但下标实参内的尺寸表达式(t.CArray[T, A * B])'*' 后仍有操作数, + # 但下标实参内的尺寸表达式(CArray[T, A * B])'*' 后仍有操作数, # 必须按乘法继续——否则下标收尾报 `expected ']'`。 if not (self._SubscriptArgs > 0 and self._AtOperandAfterStarRun()): break @@ -535,7 +535,7 @@ class ExprParserMixin(TokenStream): tok: Token = self._Peek() if tok.Type == OP and tok.Value in ('*', '**') and self._AtPtrSuffixCall(node): # `T*(x)` / `T**(x)` 指针后缀强转:解析为 cast 调用(与 - # `(T | t.CPtr)(x)` 同形)。在 trailer 循环里消费,故其后的 + # `(T | CPtr)(x)` 同形)。在 trailer 循环里消费,故其后的 # `.attr` / `[i]` / `(…)` 仍由本循环继续挂接(如 # `ast.Attribute*(expr_root).value`)。 node = self._ConsumePtrSuffixCall(node, start) @@ -628,7 +628,7 @@ class ExprParserMixin(TokenStream): - `defined(NAME)`:仅 cif/celif 条件内合法(`self._InCIfCond`), desugar 为内部标记调用 `c.@CIfdef(NAME)`;其余位置 FailFast。 - - `c.CIf` / `c.CIfdef` / `c.CIfndef`(及裸名):已删除,FailFast 指向新语法。 + - `CIf` / `CIfdef` / `CIfndef`(及裸名):已删除,FailFast 指向新语法。 """ callee: str = self._CallCalleeName(node.func) if callee in _REMOVED_CIF_NAMES: @@ -646,8 +646,7 @@ class ExprParserMixin(TokenStream): f"'defined' expects exactly one macro name (e.g. defined(MAX_SIZE)), " f"at line {start.Line}") marker: N.Call = N.Call( - func=N.Attribute(value=N.Name(id='c', ctx=N.Load()), - attr='@CIfdef', ctx=N.Load()), + func=N.Name(id='CIfdef', ctx=N.Load()), args=[node.args[0]], keywords=[]) self._FixLoc(marker, start) return marker @@ -666,8 +665,8 @@ class ExprParserMixin(TokenStream): def _ParseSliceList(self) -> N.AST: """解析下标列表:a[1] / a[1:2] / a[1:2:3] / a[1,2] / a[...] / a[::] - 下标实参内是**表达式**位置(如 `t.CArray[T, A * B]` 的尺寸),此处的 '*' - 应按乘法解析;同时 `t.CArray[str*, 4]` 的指针后缀仍要成立——两者由 + 下标实参内是**表达式**位置(如 `CArray[T, A * B]` 的尺寸),此处的 '*' + 应按乘法解析;同时 `CArray[str*, 4]` 的指针后缀仍要成立——两者由 `_AtOperandAfterStarRun`('*' 后是否还有操作数)区分,故此处登记已进入实参。 """ self._SubscriptArgs += 1 @@ -1301,7 +1300,7 @@ class ExprParserMixin(TokenStream): first: N.expr = self.ParseExpr() # Paren-less C cast `(T*)x`: the inner expression ends with a pointer suffix # (_Prev() is that suffix's tail token) and the operand follows ')'. Same - # product as `(T*)(x)` / `T*(x)`: a Call whose func is `T | t.CPtr`. + # product as `(T*)(x)` / `T*(x)`: a Call whose func is `T | CPtr`. is_ptr_cast: bool = self._PtrSuffixTail is not None and self._AtOp(')') and self._Prev() is self._PtrSuffixTail self._SkipNL() # 生成器表达式 (x for ...) @@ -1692,8 +1691,8 @@ class ExprParserMixin(TokenStream): 注解模式开启后,'_ParseTerm'/'_ParsePower' 不再把 '*' / '**' 当 乘法/幂运算消费,而由本方法统一循环消费并展开为嵌套联合类型: - int* → int | t.CPtr (i32*) - int** → (int | t.CPtr) | t.CPtr (i32**) + int* → int | CPtr (i32*) + int** → (int | CPtr) | CPtr (i32**) int****** → 6 层嵌套 (i32******) 展开为 BinOp(BitOr) 链后,TPC/VPC 现有类型解析(TypeAnnotationResolver @@ -1702,11 +1701,11 @@ class ExprParserMixin(TokenStream): 无法解析的后缀形态**响亮失败**(SyntaxError,含 行:列 + 源码片段 + 形态 + 正确写法示例),绝不静默丢弃:注解末尾若仍遗留未被 `_AtPtrSuffix` 接受的 - '*'/'**'(如 `a: int * 2` / `a: int* | t.CPtr`),判据拒绝消费即终止编译 + '*'/'**'(如 `a: int * 2` / `a: int* | CPtr`),判据拒绝消费即终止编译 (历史事故:静默退化会产出错误的指针层数)。 值引用参数注解(仅形参位有效):前导 `&` 为 ref 模式、`&temp` 为 temp 模式, - 合成联合形态 `T | t.CRef` / `T | t.CTempRef` 承载(CRef/CTempRef 非真实类, + 合成联合形态 `T | CRef` / `T | CTempRef` 承载(CRef/CTempRef 非真实类, 仅按名字识别;语义侧见 HandlesFunctions / FuncGen)。表达式位的 `&x` 不受影响。 """ ref_mode: str | None = None @@ -1757,9 +1756,9 @@ class ExprParserMixin(TokenStream): f"{tok.Value!r} 前面不是可加后缀的类型(Name / Attribute / Subscript)," f"或其后不是后缀的合法结束位置(注解结尾,或 ']' / ',' / ')' / ':' / '=')。" f"源码片段 {snippet!r}。" - f"期望形态:`T*`(1 层)/ `T**`(2 层),T 可为裸名 / t.X / mod.Type / " - f"rawptr[T] / t.CPtr[T]。" - f"正确示例:`a: t.CPtr*` / `a: rawptr*` / `a: t.X**` / " + f"期望形态:`T*`(1 层)/ `T**`(2 层),T 可为裸名 / X / mod.Type / " + f"rawptr[T] / CPtr[T]。" + f"正确示例:`a: CPtr*` / `a: rawptr*` / `a: X**` / " f"`a: rawptr[ast.AST*]` / `def f(p: int*) -> int**`。" ) if ref_mode is not None: @@ -1767,13 +1766,12 @@ class ExprParserMixin(TokenStream): return expr def _MakeRefMarker(self, base: N.expr, mode: str, tok: Token) -> N.expr: - """构造值引用标记联合:`base | t.CRef`(ref)/ `base | t.CTempRef`(temp)。 + """构造值引用标记联合:`base | CRef`(ref)/ `base | CTempRef`(temp)。 CRef / CTempRef 非真实类,仅作为注解 AST 内的名字标记(语义侧按名字识别)。 """ - marker: N.expr = N.Attribute( - value=N.Name(id='t', ctx=N.Load()), - attr='CRef' if mode == 'ref' else 'CTempRef', + marker: N.expr = N.Name( + id='CRef' if mode == 'ref' else 'CTempRef', ctx=N.Load()) node: N.BinOp = N.BinOp(left=base, op=N.BitOr(), right=marker) self._FixLoc(node, tok) @@ -1796,7 +1794,7 @@ class ExprParserMixin(TokenStream): 判据(两条同时成立): 1. base 是"类型原子"形态(Name / Attribute / Subscript)—— 即 ``ast.AST``、 - ``t.CArray[X, N]``、``rawptr[X]`` 之类; + ``CArray[X, N]``、``rawptr[X]`` 之类; 2. 该 '*'/'**' 串(可跨括号内换行 NL)之后紧跟"无右操作数"位置: ``]`` / ``,`` / ``)`` / ``:`` / ``=``(全局),或注解模式下的 NEWLINE / NL / ENDMARKER / ``;``。 @@ -1830,7 +1828,7 @@ class ExprParserMixin(TokenStream): return False def _ConsumePtrSuffix(self, expr: N.expr) -> N.expr: - """消费连续的 C 风格指针后缀('*' 一层 / '**' 两层),展开为 base | t.CPtr 链。""" + """消费连续的 C 风格指针后缀('*' 一层 / '**' 两层),展开为 base | CPtr 链。""" while True: tok: Token = self._Peek() if tok.Type == OP and tok.Value == '*': @@ -1864,7 +1862,7 @@ class ExprParserMixin(TokenStream): 与 `_AtPtrSuffix` 互补:后者判「'*' 后是无右操作数位置」(']' / ',' / ')' / ':' / '=' / 行尾 / ';' ⇒ 指针后缀),本方法判其反面('*' 后是 NAME / NUMBER / STRING / FSTRING 或 '(' / '[' / '{' / 一元前缀 ⇒ 乘法)。用于下标实参内区分 - `t.CArray[T, A * B]`(乘法)与 `t.CArray[T*, 4]`(指针后缀)。 + `CArray[T, A * B]`(乘法)与 `CArray[T*, 4]`(指针后缀)。 """ j: int = 0 while True: @@ -1923,17 +1921,16 @@ class ExprParserMixin(TokenStream): def _ConsumePtrSuffixCall(self, base: N.expr, start: Token) -> N.expr: """把已认定为 `T*(...)` 的指针后缀强转解析为**调用**。 - 产物与既有强转形态 `(T | t.CPtr)(...)` 逐字同形:同为 `ast.Call` - (func = `T` 展开的 `base | t.CPtr` 链,args/keywords = 括号实参), + 产物与既有强转形态 `(T | CPtr)(...)` 逐字同形:同为 `ast.Call` + (func = `T` 展开的 `base | CPtr` 链,args/keywords = 括号实参), 不新造第二套 cast 表示。 """ func: N.expr = self._ConsumePtrSuffix(base) return self._ParseCallTail(func, start) def _MakePtrType(self, base: N.expr, tok: Token) -> N.expr: - """构造一层指针包装:base | t.CPtr。""" - cptr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='CPtr', ctx=N.Load()) + """构造一层指针包装:base | CPtr。""" + cptr: N.expr = N.Name(id='CPtr', ctx=N.Load()) node: N.BinOp = N.BinOp(left=base, op=N.BitOr(), right=cptr) self._FixLoc(node, tok) return node diff --git a/lib/vast/Parser.py b/lib/vast/Parser.py index b701153..0a784d4 100644 --- a/lib/vast/Parser.py +++ b/lib/vast/Parser.py @@ -28,8 +28,8 @@ from lib.vast.Tokenizer import ( # 语法:`virtual class` / `novirtual class` / `virtual def` / `novirtual def` # (修饰符写在 class/def **之前**,允许与修饰对象同行,也允许各占一行)。 # -# 语义:与既有装饰器**同一套表示**——virtual → `@t.CVTable`, -# novirtual → `@t.NoVTable`。本层只"合成装饰器节点",不新增第二套表示: +# 语义:与既有装饰器**同一套表示**——virtual → `@CVTable`, +# novirtual → `@NoVTable`。本层只"合成装饰器节点",不新增第二套表示: # - 类级:CVTable 强制有 vtable / NoVTable 强制无 vtable # (TPC:HandlesClassDef._resolve_class_flags 读 ClassDef.decorator_list # 的 CVTable/NoVTable;VPC:ClassGenBase._detect_vtable_status) @@ -62,7 +62,7 @@ _VIRTUAL_EXAMPLE: str = ( 'novirtual class B: novirtual def helper(self) -> int: ...' ) -# tls 修饰符(软关键字):`tls def f(...)` ⇒ 合成既有装饰器 `@t.TLS` +# tls 修饰符(软关键字):`tls def f(...)` ⇒ 合成既有装饰器 `@TLS` #(一次性初始化守卫,见 HandlesFunctions 的 TLS 分支)。与 virtual/novirtual 同一套 # "软关键字 + 合成既有装饰器"表示,不新增第二套语义;只在语句起始且后随 def 时生效, # 故 `tls: local = local()` / `tls.set(...)` 等把 tls 当标识符的写法逐字不变。 @@ -75,8 +75,8 @@ _TLS_KEYWORD: str = 'tls' # 语义(用户 2026-10-01 定):与 class 同形,但**只能表示数据类型**: # - 禁止 virtual / novirtual 修饰(见 _ParseVirtualModified 的显式拦截); # - 禁止类体内定义 def(见 _ParseStructDef 的 fail-fast); -# - 解析期合成 `@t.NoVTable` 装饰器 + 追加 `t.CStruct` 标记基类, -# 与手写 `@t.NoVTable class X(t.CStruct):` 逐字段同形 ⇒ 下游 +# - 解析期合成 `@NoVTable` 装饰器 + 追加 `CStruct` 标记基类, +# 与手写 `@NoVTable class X(CStruct):` 逐字段同形 ⇒ 下游 # (HandlesClassDef._resolve_class_flags / _MARKER_BASES)零新增判据。 # - 允许出现在 REnum 内部(REnum 变体本就是嵌套 ClassDef),也允许 struct 内 # 再写 struct(与 class 内写 class 同口径)。 @@ -93,7 +93,7 @@ _STRUCT_EXAMPLE: str = ( # 解析时 desugar 为 is_switch=True 的 N.Match。 _SWITCH_KEYWORD: str = 'switch' -# fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为 `c.NoBreak()` +# fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为 `NoBreak()` # 标记调用(switch 生成侧据此让 case 体不自动跳出 switch,落到下一个 case)。 _FALLTHROUGH_KEYWORD: str = 'fallthrough' @@ -107,13 +107,13 @@ _FALLTHROUGH_KEYWORD: str = 'fallthrough' # celif E: → 同链下一个 If(test=c.@CIf(E), ...)(挂在上一支 orelse) # celse: → 普通 orelse # defined(N) → c.@CIfdef(N) 标记调用 -# 标记(c.@CIf / c.@CIfdef)是内部表示:用户写 c.CIf(...) 在 ExprParser 处报错。 +# 标记(c.@CIf / c.@CIfdef)是内部表示:用户写 CIf(...) 在 ExprParser 处报错。 _CIF_KEYWORD: str = 'cif' _CELIF_KEYWORD: str = 'celif' _CELSE_KEYWORD: str = 'celse' # 内部 CIf 族标记:desugar 产出的调用名(用户不可写)。 # 与 Viper 侧解析器(includes/ast/parser.vp 的 _MakeCifMarker)同拼写:属性名带前导 '@', -# 词法器无法产出该拼写,故用户写的 c.CIf(...) 永远不会命中此标记(会被 ExprParser 拒绝)。 +# 词法器无法产出该拼写,故用户写的 CIf(...) 永远不会命中此标记(会被 ExprParser 拒绝)。 _CIF_MARKER: str = '@CIf' _CIFDEF_MARKER: str = '@CIfdef' # cif 语句起始判定:语句起始 NAME('cif') 后紧跟这些运算符时按普通语句(赋值/注解) @@ -166,10 +166,10 @@ class Parser(ExprParserMixin): tok: Token = self._Peek() if tok.Type == NAME: v: str = tok.Value - # extern 函数声明(FFI,等价 t.State)——必须在软关键字 def 分派之前 + # extern 函数声明(FFI,等价 State)——必须在软关键字 def 分派之前 if v == 'extern': return self._ParseExternDef() - # export 函数声明(等价 t.CExport,裸名导出不增加 SHA1 头)—— + # export 函数声明(等价 CExport,裸名导出不增加 SHA1 头)—— # 必须在软关键字 def 分派之前 if v == 'export': return self._ParseExportDef() @@ -177,25 +177,25 @@ class Parser(ExprParserMixin): # 仅 `static def 名字` 形态判定为函数定义——判据必须同时要求第二个 token # 是 `def`,故 `static = 5` / `static x = 5` 不会被误吃成函数定义。 # 变量形式 `static 名字: 类型 = 值` 不在本层处理,由 SymbolUtils 的前置 - # 修饰符展开统一脱糖为 `名字: t.CStatic | 类型 = 值`。 + # 修饰符展开统一脱糖为 `名字: CStatic | 类型 = 值`。 if (v == 'static' and self._Peek(1).Type == NAME and self._Peek(1).Value == 'def'): return self._ParseStaticDef() - # define 宏函数定义(与 def 语义一致,返回注解自动追加 t.CDefine + # define 宏函数定义(与 def 语义一致,返回注解自动追加 CDefine # 标记为宏函数;软关键字:仅"define + 标识符"形态才判定为函数定义, # 变量名/调用(define = 5、define(x))不受影响)——必须在软关键字 # def 分派之前 if v == 'define' and self._Peek(1).Type == NAME: return self._ParseDefineDef() # virtual / novirtual 修饰符(软关键字):只在"语句起始 + 紧跟 class/def" - # 时生效,合成既有装饰器 @t.CVTable / @t.NoVTable(见 _ParseVirtualModified)。 + # 时生效,合成既有装饰器 @CVTable / @NoVTable(见 _ParseVirtualModified)。 # 放在 def/class 分派之前:修饰符必须先被消费,class/def 才能照常分派。 # 与软关键字 fn→def 的先后关系:`.vp` 源码在进入本解析器之前已过 # SymbolUtils.ExpandSoftKeywords(fn/fun/func/function → def), # 故 `virtual fn m()` 在此已是 `virtual def m()`;本层只认 class/def。 if v in _VIRTUAL_MARKERS: return self._ParseVirtualModified() - # tls 修饰符(软关键字):语句起始 + 紧跟 def 时生效,合成既有装饰器 @t.TLS。 + # tls 修饰符(软关键字):语句起始 + 紧跟 def 时生效,合成既有装饰器 @TLS。 if v == _TLS_KEYWORD and self._IsTlsDefStart(): return self._ParseTlsModified() # 软关键字函数定义:fn/fun/func/function + 标识符 @@ -242,7 +242,7 @@ class Parser(ExprParserMixin): if v == _SWITCH_KEYWORD: return self._ParseSwitch() # fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为 - # `c.NoBreak()` 标记调用,由 switch 生成侧消费(case 体因此不自动 + # `NoBreak()` 标记调用,由 switch 生成侧消费(case 体因此不自动 # 跳出 switch)。合法位置由生成侧判定:写进 match 或 switch 之外 # 一律 FailFastError。 if v == _FALLTHROUGH_KEYWORD: @@ -289,7 +289,7 @@ class Parser(ExprParserMixin): # fallthrough 关键字(语句级) # ================================================================== def _ParseFallThrough(self) -> N.stmt: - """`fallthrough` 脱糖为 `c.NoBreak()`(switch 生成侧识别的 fallthrough 标记) + """`fallthrough` 脱糖为 `NoBreak()`(switch 生成侧识别的 fallthrough 标记) 合法位置只有 switch 的 case 体;写进 match 或 switch 之外由生成侧 (HandlesMatch / HandlesBody)fail-fast。 @@ -297,8 +297,7 @@ class Parser(ExprParserMixin): tok: Token = self._Peek() self._Next() marker: N.Call = N.Call( - func=N.Attribute(value=N.Name(id='c', ctx=N.Load()), - attr='NoBreak', ctx=N.Load()), + func=N.Name(id='NoBreak', ctx=N.Load()), args=[], keywords=[]) node: N.Expr = N.Expr(value=marker) self._FixLoc(node, tok) @@ -423,9 +422,9 @@ class Parser(ExprParserMixin): @staticmethod def _IsCTypedefAnnotation(annotation: N.expr | None) -> bool: - """注解是否为 typedef 标记(裸 `CTypedef` / `t.CTypedef` / 含它的 `|` 联合)。 + """注解是否为 typedef 标记(裸 `CTypedef` / `CTypedef` / 含它的 `|` 联合)。 - 用于把 typedef 的右值按**类型位置**解析(`X: t.CTypedef = const uint16*` + 用于把 typedef 的右值按**类型位置**解析(`X: CTypedef = const uint16*` 里的 `*` 后缀由 _ParseTypeAnnotation 消费,与注解位同一规则;描述符 `const`/`volatile` 已由 SymbolUtils._ExpandTypeDescriptors 在文本层展开)。 仅按标记名判定,不依赖 import 别名表(与 VPC `_IsCTypedefAnnotation` 同口径)。 @@ -447,7 +446,7 @@ class Parser(ExprParserMixin): 注意:仅当目标为简单 Name/Attribute/Subscript 且后随 ':' 时匹配; 元组/列表解包不做注解(返回 None 走普通路径)。 - `t.CTypedef` 注解的右值是**类型**而非一般表达式(`const str` / `uint16*`), + `CTypedef` 注解的右值是**类型**而非一般表达式(`const str` / `uint16*`), 故走 `_ParseTypeAnnotation`(与注解位同一路径,支持 C 式指针后缀)。 """ start: Token = self._Peek() @@ -725,7 +724,7 @@ class Parser(ExprParserMixin): # `@deco` 与 `virtual class`/`virtual def` 组合:合成标记追加在既有装饰器之后 return self._ParseVirtualModified(decorators=decorator_list) if tok.Type == NAME and tok.Value == _TLS_KEYWORD and self._IsTlsDefStart(): - # `@deco` 与 `tls def` 组合:合成 @t.TLS 追加在既有装饰器之后 + # `@deco` 与 `tls def` 组合:合成 @TLS 追加在既有装饰器之后 return self._ParseTlsModified(decorators=decorator_list) raise SyntaxError(f"decorator must be followed by def/class, got {tok.Value!r}") @@ -760,9 +759,9 @@ class Parser(ExprParserMixin): def _ParseVirtualModified(self, decorators: list[N.expr] | None = None) -> N.stmt: """`virtual class` / `novirtual class` / `virtual def` / `novirtual def`。 - 合成 `@t.CVTable` / `@t.NoVTable` 装饰器后交给 _ParseClassDef / + 合成 `@CVTable` / `@NoVTable` 装饰器后交给 _ParseClassDef / _ParseFunctionDef,产出与**手写同名装饰器**逐字段同形的 AST - (decorator_list 多一个 Attribute(Name('t', Load), 'CVTable'|'NoVTable', Load)), + (decorator_list 多一个 Name('CVTable'|'NoVTable', Load)), 故下游(_resolve_class_flags / _should_method_be_virtual 同族判据)零新增分支。 非法形态**响亮失败**(不静默丢修饰符): @@ -786,7 +785,7 @@ class Parser(ExprParserMixin): # 单独报文(而不是落到通用"后随非 class/def")以便直接给出修法。 raise self._StructSyntaxError( f'{mod.Value} struct 非法:struct 禁止 virtual/novirtual 修饰', mod, - 'struct 天然无虚表(解析期已合成 @t.NoVTable),请直接写 `struct X:`;' + 'struct 天然无虚表(解析期已合成 @NoVTable),请直接写 `struct X:`;' '需要虚表语义请改用 class。') raise self._VirtualSyntaxError( f"{mod.Value!r} 后随 {nxt_text}(非 class/def)", mod, @@ -799,8 +798,7 @@ class Parser(ExprParserMixin): f'{mod.Value} def 描述的是「类体内方法的虚/非虚」,' f'模块级 / 函数体 / 分支体内没有可归属的类。') self._Next() # 消费修饰符 - deco: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr=marker, ctx=N.Load()) + deco: N.expr = N.Name(id=marker, ctx=N.Load()) self._FixLoc(deco, mod) deco_list: list[N.expr] = list(decorators or []) deco_list.append(deco) @@ -824,16 +822,15 @@ class Parser(ExprParserMixin): return False def _ParseTlsModified(self, decorators: list[N.expr] | None = None) -> N.stmt: - """`tls def f(...)`:消费 tls,合成 `@t.TLS` 后交给 _ParseFunctionDef。 + """`tls def f(...)`:消费 tls,合成 `@TLS` 后交给 _ParseFunctionDef。 - 与手写 `@t.TLS` 逐字段同形(decorator_list 追加 - Attribute(Name('t', Load), 'TLS', Load)),故下游一次性初始化的守卫生成路径 + 与手写 `@TLS` 逐字段同形(decorator_list 追加 + Name('TLS', Load)),故下游一次性初始化的守卫生成路径 (HandlesFunctions 的 TLS 分支)零新增判据。tls 对方法与模块级函数同样生效。 """ mod: Token = self._Peek() # tls self._Next() # 消费修饰符 - deco: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='TLS', ctx=N.Load()) + deco: N.expr = N.Name(id='TLS', ctx=N.Load()) self._FixLoc(deco, mod) deco_list: list[N.expr] = list(decorators or []) deco_list.append(deco) @@ -852,7 +849,7 @@ class Parser(ExprParserMixin): f"[TPC] struct 定义非法({detail}):行 {tok.Line} 列 {tok.Col}," f"源码片段 {self._SourceLine(tok.Line).strip()!r}。" f"struct 与 class 同形,但**只能表示数据类型**:" - f"① 禁止 virtual / novirtual 修饰(struct 天然无虚表,已内置 @t.NoVTable);" + f"① 禁止 virtual / novirtual 修饰(struct 天然无虚表,已内置 @NoVTable);" f"② 禁止在 struct 内定义 def(需要方法请改用 class);" f"③ 允许在 REnum 内作为变体、也允许 struct 内再写 struct。" f"正确示例:{_STRUCT_EXAMPLE}。" @@ -862,28 +859,26 @@ class Parser(ExprParserMixin): ) def _ParseStructDef(self, decorators: list[N.expr] | None = None) -> N.ClassDef: - """`struct X:` / `struct X(Base):` → 与 `@t.NoVTable class X(t.CStruct):` + """`struct X:` / `struct X(Base):` → 与 `@NoVTable class X(CStruct):` 逐字段同形的 ClassDef(与 VPC 的 _parse_structdef 同口径)。 实现:复用 _ParseClassDef 的完整解析路径(类型参数 / 基类 / 关键字实参 / 类体套件),只在**解析前后**补三件事: - · 解析前把合成的 `@t.NoVTable` 追加进装饰器列表(与 virtual/novirtual + · 解析前把合成的 `@NoVTable` 追加进装饰器列表(与 virtual/novirtual 同款表示)⇒ 类级强制无虚表,即使父类带虚表; - · 解析后把 `t.CStruct` 标记基类**追加**到 bases 末尾(不提位用户基类, + · 解析后把 `CStruct` 标记基类**追加**到 bases 末尾(不提位用户基类, 真实父类解析顺序不变)⇒ 数据类语义(_MARKER_BASES 认它,不当真实父类); · 解析后校验类体**直接子节点**里没有 def —— struct 只能表示数据类型。 _ParseClassDef 的首个 `_Next()` 消费的正是 `struct` 关键字本身,故本函数 不预先消费,行号/列号与写法均继承自该 token。 """ start: Token = self._Peek() # struct(由 _ParseClassDef 的 _Next() 消费) - deco: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='NoVTable', ctx=N.Load()) + deco: N.expr = N.Name(id='NoVTable', ctx=N.Load()) self._FixLoc(deco, start) deco_list: list[N.expr] = list(decorators or []) deco_list.append(deco) node: N.ClassDef = self._ParseClassDef(decorators=deco_list) - marker_base: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='CStruct', ctx=N.Load()) + marker_base: N.expr = N.Name(id='CStruct', ctx=N.Load()) self._FixLoc(marker_base, start) node.bases.append(marker_base) for item in node.body: @@ -926,7 +921,7 @@ class Parser(ExprParserMixin): return node def _ParseExternDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef: - """解析 extern 函数声明(FFI,与 t.State 作用相当)。 + """解析 extern 函数声明(FFI,与 State 作用相当)。 允许语法(均声明不定义,不生成函数体): extern def A(x: int) -> int: pass @@ -934,7 +929,7 @@ class Parser(ExprParserMixin): extern def A(x: int) -> int extern A(x: int) -> int - 产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.State`` + 产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | State`` 以复用 TPC 的 IsState 路径;并设自定义属性 ``Extern = True`` 供 Unparser 还原 extern 语法。 """ @@ -960,9 +955,8 @@ class Parser(ExprParserMixin): type_comment=None, type_params=type_params, ) node.Extern = True - # 返回注解改写为 <原类型> | t.State,使 TPC 识别为 State 函数(仅声明) - state_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='State', ctx=N.Load()) + # 返回注解改写为 <原类型> | State,使 TPC 识别为 State 函数(仅声明) + state_attr: N.expr = N.Name(id='State', ctx=N.Load()) if returns is not None: node.returns = N.BinOp(left=returns, op=N.BitOr(), right=state_attr) else: @@ -971,7 +965,7 @@ class Parser(ExprParserMixin): return node def _ParseExportDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef: - """解析 export 函数声明(等价 t.CExport,导出裸名、不加模块 SHA1 头)。 + """解析 export 函数声明(等价 CExport,导出裸名、不加模块 SHA1 头)。 允许语法(与 extern 对称,配不配 def 都一样): export def A(x: int) -> int: pass @@ -979,7 +973,7 @@ class Parser(ExprParserMixin): export def A(x: int) -> int export A(x: int) -> int - 产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.CExport`` + 产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | CExport`` 以复用 TPC 的 CExport 路径(符号名不增加 SHA1 前缀);并设自定义 属性 ``Export = True`` 供 Unparser 还原 export 语法。 """ @@ -1005,10 +999,9 @@ class Parser(ExprParserMixin): type_comment=None, type_params=type_params, ) node.Export = True - # 返回注解改写为 <原类型> | t.CExport,使 TPC 识别为 CExport 函数 + # 返回注解改写为 <原类型> | CExport,使 TPC 识别为 CExport 函数 # (导出裸名,不增加模块 SHA1 头;有条件情况下导出) - export_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='CExport', ctx=N.Load()) + export_attr: N.expr = N.Name(id='CExport', ctx=N.Load()) if returns is not None: node.returns = N.BinOp(left=returns, op=N.BitOr(), right=export_attr) else: @@ -1017,7 +1010,7 @@ class Parser(ExprParserMixin): return node def _ParseStaticDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef: - """解析 static 函数定义(等价 ``@t.CStatic``,与 ViperC 的 + """解析 static 函数定义(等价 ``@CStatic``,与 ViperC 的 `_ParseStaticModified` 同源)。 允许语法(与 export/extern 对称,配不配 def 都一样): @@ -1025,11 +1018,11 @@ class Parser(ExprParserMixin): static A(x: int) -> int: ... 与 export/extern 的**两处不同**: - - **不改写返回注解**(不追加 `| t.CStatic` / `| t.State`):CStatic 是 + - **不改写返回注解**(不追加 `| CStatic` / `| State`):CStatic 是 函数属性,由下面的合成装饰器承载,返回类型语义逐字不变; - - **合成 `@t.CStatic` 装饰器**追加在既有装饰器之后,产出与**手写 - `@t.CStatic`** 逐字段同形(decorator_list 多一个 - Attribute(Name('t', Load), 'CStatic', Load)),下游零新增判据。 + - **合成 `@CStatic` 装饰器**追加在既有装饰器之后,产出与**手写 + `@CStatic`** 逐字段同形(decorator_list 多一个 + Name('CStatic', Load)),下游零新增判据。 另设自定义属性 ``Static = True`` 供 Unparser 还原 static 语法 (镜像 Extern/Export;因 FunctionDef 的 __slots__ 槽位未含 Static 且 @@ -1051,9 +1044,8 @@ class Parser(ExprParserMixin): if self._AtOp(':'): self._Next() body = self._ParseSuite() - # 合成 @t.CStatic 装饰器(追加在既有装饰器之后) - static_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='CStatic', ctx=N.Load()) + # 合成 @CStatic 装饰器(追加在既有装饰器之后) + static_attr: N.expr = N.Name(id='CStatic', ctx=N.Load()) self._FixLoc(static_attr, start) deco_list: list[N.expr] = list(decorators or []) deco_list.append(static_attr) @@ -1066,7 +1058,7 @@ class Parser(ExprParserMixin): # 注:FunctionDef 是 __slots__ 类(见 vast/Nodes.py 的 _FUNC_ATTRS,当前槽位 # 为 Extern/Export/Define,未含 Static)——补槽位需改第三个文件(本次不许可), # 故仅在槽位存在时设置,避免 AttributeError 中断解析;下游对 static 函数的 - # 识别靠上面合成的 @t.CStatic 装饰器(HandlesFunctions 的存储类装饰器分支), + # 识别靠上面合成的 @CStatic 装饰器(HandlesFunctions 的存储类装饰器分支), # 与 virtual/novirtual 仅合成装饰器同构。 if hasattr(type(node), 'Static'): node.Static = True @@ -1080,8 +1072,8 @@ class Parser(ExprParserMixin): define A(x: int) -> int: ... define A(x: int): ... - 产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.CDefine`` - (无显式返回注解时单独 ``t.CDefine``),使 TPC/VPC 复用既有的 + 产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | CDefine`` + (无显式返回注解时单独 ``CDefine``),使 TPC/VPC 复用既有的 CDefine 宏函数识别路径(StubGen 原样保留生成 C #define、 alwaysinline 内联);并设自定义属性 ``Define = True`` 供 Unparser 还原 define 语法。 @@ -1104,10 +1096,9 @@ class Parser(ExprParserMixin): type_comment=None, type_params=type_params, ) node.Define = True - # 返回注解改写为 <原类型> | t.CDefine,使下游识别为宏函数 + # 返回注解改写为 <原类型> | CDefine,使下游识别为宏函数 # (StubGen 保留原样输出 C #define;TPC 标记 alwaysinline 内联) - define_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()), - attr='CDefine', ctx=N.Load()) + define_attr: N.expr = N.Name(id='CDefine', ctx=N.Load()) if returns is not None: node.returns = N.BinOp(left=returns, op=N.BitOr(), right=define_attr) else: @@ -1298,7 +1289,7 @@ class Parser(ExprParserMixin): return node # ================================================================== - # cif / celif / celse 编译期条件编译(软关键字,desugar 到 c.CIf 标记) + # cif / celif / celse 编译期条件编译(软关键字,desugar 到 CIf 标记) # ================================================================== def _IsCIfStatementStart(self) -> bool: """语句起始 NAME('cif') 是否按 cif 语句解析。 @@ -1312,9 +1303,8 @@ class Parser(ExprParserMixin): return True def _MakeCIfMarkerCall(self, attr: str, expr: N.expr, start: Token) -> N.Call: - """构造内部标记调用 `c.(expr)`(用户不可写;cif/defined 的 desugar)。""" - func: N.Attribute = N.Attribute( - value=N.Name(id='c', ctx=N.Load()), attr=attr, ctx=N.Load()) + """构造内部标记调用 `(expr)`(用户不可写;cif/defined 的 desugar)。""" + func: N.Name = N.Name(id=attr, ctx=N.Load()) self._FixLoc(func, start) call: N.Call = N.Call(func=func, args=[expr], keywords=[]) self._FixLoc(call, start) diff --git a/lib/vast/Unparser.py b/lib/vast/Unparser.py index 6cd124a..d2a8632 100644 --- a/lib/vast/Unparser.py +++ b/lib/vast/Unparser.py @@ -1,6 +1,6 @@ """vast.unparser - AST 还原为源码字符串(与 ast.unparse 语义一致) -TPC 编译器多处用 ``ast.unparse`` 提取类型注解字符串(如 ``t.CArray[...]``、 +TPC 编译器多处用 ``ast.unparse`` 提取类型注解字符串(如 ``CArray[...]``、 ``list[i32, N]``、数组维度、默认值文本等)。本模块实现全部节点类型的 源码还原,保证 ``import vast as ast`` 后这些调用零修改。 """ @@ -88,22 +88,19 @@ class Unparser: ret: str = '' returns: N.expr | None = node.returns if is_extern and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr): - # 还原 extern 原始注解:去掉改写时追加的 | t.State + # 还原 extern 原始注解:去掉改写时追加的 | State right: N.expr = returns.right - if (isinstance(right, N.Attribute) and right.attr == 'State' - and isinstance(right.value, N.Name) and right.value.id == 't'): + if isinstance(right, N.Name) and right.id == 'State': returns = returns.left if is_export and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr): - # 还原 export 原始注解:去掉改写时追加的 | t.CExport + # 还原 export 原始注解:去掉改写时追加的 | CExport right = returns.right - if (isinstance(right, N.Attribute) and right.attr == 'CExport' - and isinstance(right.value, N.Name) and right.value.id == 't'): + if isinstance(right, N.Name) and right.id == 'CExport': returns = returns.left if is_define and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr): - # 还原 define 原始注解:去掉改写时追加的 | t.CDefine + # 还原 define 原始注解:去掉改写时追加的 | CDefine right = returns.right - if (isinstance(right, N.Attribute) and right.attr == 'CDefine' - and isinstance(right.value, N.Name) and right.value.id == 't'): + if isinstance(right, N.Name) and right.id == 'CDefine': returns = returns.left if returns is not None: ret = f' -> {self._expr(returns)}' diff --git a/lib/vast_c/vast_c.c b/lib/vast_c/vast_c.c index 925d529..d5bcc28 100644 --- a/lib/vast_c/vast_c.c +++ b/lib/vast_c/vast_c.c @@ -3067,7 +3067,7 @@ static PyObject *ParseCallTail(Parser *P, PyObject *Func, Token *Start) { return Node; } -/* 被调用者限定名:Name('X')→'X';Attribute(Name('c'),'X')→'c.X';否则 NULL(无异常)。 */ +/* 被调用者限定名:Name('X')→'X';Attribute(Name('M'),'X')→'M.X';否则 NULL(无异常)。 */ static PyObject *MakeCifMarkerCall(Parser *P, const char *AttrName, PyObject *Expr, Token *Start); static PyObject *CalleeQualName(PyObject *Func) { if (NodeIs(Func, "Name")) { @@ -5600,36 +5600,20 @@ static PyObject *ParseFunctionDef(Parser *P, int IsAsync, PyObject *Decorators) return Node; } -/* 构造 t.Attr 注解节点:Attribute(value=Name('t', Load), attr=AttrName, ctx=Load) */ +/* 构造内建 attr 注解节点:Name(AttrName, Load) */ static PyObject *MakeTAttrNode(Parser *P, const char *AttrName) { PyObject *Load = MakeCtx(P, "Load"); - PyObject *TName = PyUnicode_FromString("t"); - if (Load == NULL || TName == NULL) { + PyObject *AttrStr = AttrName ? PyUnicode_FromString(AttrName) : NULL; + if (Load == NULL || AttrStr == NULL) { Py_XDECREF(Load); - Py_XDECREF(TName); - return NULL; - } - PyObject *ArgvN[2] = { TName, Load }; - PyObject *TNode = NewNode(P, "Name", ArgvN, 2); - Py_DECREF(TName); - Py_DECREF(Load); - if (TNode == NULL) { - return NULL; - } - PyObject *Load2 = MakeCtx(P, "Load"); - PyObject *AttrStr = PyUnicode_FromString(AttrName); - if (Load2 == NULL || AttrStr == NULL) { - Py_XDECREF(TNode); - Py_XDECREF(Load2); Py_XDECREF(AttrStr); return NULL; } - PyObject *ArgvA[3] = { TNode, AttrStr, Load2 }; - PyObject *AttrNode = NewNode(P, "Attribute", ArgvA, 3); - Py_DECREF(TNode); + PyObject *ArgvN[2] = { AttrStr, Load }; + PyObject *Node = NewNode(P, "Name", ArgvN, 2); Py_DECREF(AttrStr); - Py_DECREF(Load2); - return AttrNode; + Py_DECREF(Load); + return Node; } /* extern/export 函数声明(FFI/裸名导出,对齐 vast Parser._ParseExternDef/_ParseExportDef)。 @@ -6245,54 +6229,37 @@ static int IsCIfStatementStart(Parser *P) { return 1; } -/* 构造内部标记调用 `c.(Expr)`(用户不可写)。 */ +/* 构造内部标记调用 `(Expr)`。 */ static PyObject *MakeCifMarkerCall(Parser *P, const char *AttrName, PyObject *Expr, Token *Start) { - PyObject *Load1 = MakeCtx(P, "Load"); - PyObject *IdC = Load1 ? PyUnicode_FromString("c") : NULL; - if (Load1 == NULL || IdC == NULL) { - Py_XDECREF(Load1); - Py_XDECREF(IdC); - return NULL; - } - PyObject *NameArgv[2] = { IdC, Load1 }; - PyObject *NameNode = NewNode(P, "Name", NameArgv, 2); - Py_DECREF(IdC); - Py_DECREF(Load1); - if (NameNode == NULL) { - return NULL; - } - FixLoc(P, NameNode, Start); - PyObject *Load2 = MakeCtx(P, "Load"); - PyObject *AttrStr = Load2 ? PyUnicode_FromString(AttrName) : NULL; - if (Load2 == NULL || AttrStr == NULL) { - Py_XDECREF(Load2); + PyObject *Load = MakeCtx(P, "Load"); + PyObject *AttrStr = Load ? PyUnicode_FromString(AttrName) : NULL; + if (Load == NULL || AttrStr == NULL) { + Py_XDECREF(Load); Py_XDECREF(AttrStr); - Py_DECREF(NameNode); return NULL; } - PyObject *AttrArgv[3] = { NameNode, AttrStr, Load2 }; - PyObject *AttrNode = NewNode(P, "Attribute", AttrArgv, 3); + PyObject *NameArgv[2] = { AttrStr, Load }; + PyObject *FnNode = NewNode(P, "Name", NameArgv, 2); Py_DECREF(AttrStr); - Py_DECREF(Load2); - Py_DECREF(NameNode); - if (AttrNode == NULL) { + Py_DECREF(Load); + if (FnNode == NULL) { return NULL; } - FixLoc(P, AttrNode, Start); + FixLoc(P, FnNode, Start); PyObject *Args = NewList(); PyObject *Kw = NewList(); if (Args == NULL || Kw == NULL) { Py_XDECREF(Args); Py_XDECREF(Kw); - Py_DECREF(AttrNode); + Py_DECREF(FnNode); return NULL; } PyList_Append(Args, Expr); - PyObject *CallArgv[3] = { AttrNode, Args, Kw }; + PyObject *CallArgv[3] = { FnNode, Args, Kw }; PyObject *CallNode = NewNode(P, "Call", CallArgv, 3); Py_DECREF(Args); Py_DECREF(Kw); - Py_DECREF(AttrNode); + Py_DECREF(FnNode); if (CallNode == NULL) { return NULL; } @@ -7114,54 +7081,37 @@ static PyObject *ParseSwitch(Parser *P) { return Node; } -/* `fallthrough` 脱糖为 `c.NoBreak()`(switch 生成侧识别的 fallthrough 标记) */ +/* `fallthrough` 脱糖为 `NoBreak()`(switch 生成侧识别的 fallthrough 标记) */ static PyObject *ParseFallThrough(Parser *P) { Token *Start = NextTok(P); /* fallthrough */ PyObject *Load1 = MakeCtx(P, "Load"); - PyObject *IdC = Load1 ? PyUnicode_FromString("c") : NULL; - if (Load1 == NULL || IdC == NULL) { + PyObject *NameStr = Load1 ? PyUnicode_FromString("NoBreak") : NULL; + if (Load1 == NULL || NameStr == NULL) { Py_XDECREF(Load1); - Py_XDECREF(IdC); + Py_XDECREF(NameStr); return NULL; } - PyObject *NameArgv[2] = { IdC, Load1 }; - PyObject *NameNode = NewNode(P, "Name", NameArgv, 2); - Py_DECREF(IdC); + PyObject *NameArgv[2] = { NameStr, Load1 }; + PyObject *FnNode = NewNode(P, "Name", NameArgv, 2); + Py_DECREF(NameStr); Py_DECREF(Load1); - if (NameNode == NULL) { + if (FnNode == NULL) { return NULL; } - FixLoc(P, NameNode, Start); - PyObject *Load2 = MakeCtx(P, "Load"); - PyObject *AttrStr = Load2 ? PyUnicode_FromString("NoBreak") : NULL; - if (Load2 == NULL || AttrStr == NULL) { - Py_XDECREF(Load2); - Py_XDECREF(AttrStr); - Py_DECREF(NameNode); - return NULL; - } - PyObject *AttrArgv[3] = { NameNode, AttrStr, Load2 }; - PyObject *AttrNode = NewNode(P, "Attribute", AttrArgv, 3); - Py_DECREF(AttrStr); - Py_DECREF(Load2); - Py_DECREF(NameNode); - if (AttrNode == NULL) { - return NULL; - } - FixLoc(P, AttrNode, Start); + FixLoc(P, FnNode, Start); PyObject *Args = NewList(); PyObject *Keywords = NewList(); if (Args == NULL || Keywords == NULL) { Py_XDECREF(Args); Py_XDECREF(Keywords); - Py_DECREF(AttrNode); + Py_DECREF(FnNode); return NULL; } - PyObject *CallArgv[3] = { AttrNode, Args, Keywords }; + PyObject *CallArgv[3] = { FnNode, Args, Keywords }; PyObject *CallNode = NewNode(P, "Call", CallArgv, 3); Py_DECREF(Args); Py_DECREF(Keywords); - Py_DECREF(AttrNode); + Py_DECREF(FnNode); if (CallNode == NULL) { return NULL; }