Files
TransPyC/lib/core/SymbolInserter.py
T
TermiNexus c83fc752c6 fix(sizeof,parse): 尺寸链去静默兜底,解析报错可定位,补 C 解析器缺口
StructGen: _get_struct_size/_get_align 去 opaque→8/ptr_size、未知→4 兜底并补 VectorType;LiteralStructType.fields→.elements(llvmlite 无 fields,必然 AttributeError)

HandlesClassDef: union 载荷尺寸经不存在的 ir.DataLayout 静默退化成 8 字节;HandlesExprCall/ExprBuiltin: sizeof 各静默 0 分支改 fail-fast,数组元素 sizeof 统一走 _get_struct_size

HandlesFor: nonlocal struct/array 堆分配不再退化成 malloc(8)

vast/vast_c: 补一元 * / & 解析,装饰器后 extern/export 分派修复,C 侧报错带 token 与行号;StubGen.Converter: 宏展开丢尾随空行修 .pyi 缩进非法

其余为 rawptr 迁移 / fail-fast 口径等历史改动一并入库
2026-09-26 19:27:22 +08:00

94 lines
4.3 KiB
Python

"""Pass 3: SymbolInserter — 将解析后的符号插入 SymbolTable(主命名空间)"""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from lib.core.SymbolTable import SymbolTable
from lib.core.SymbolData import ModuleSymbols
class SymbolInserter:
"""将解析后的符号插入 SymbolTable 的主命名空间(无前缀)"""
def __init__(self, symbol_table: SymbolTable) -> None:
self._symtab: SymbolTable = symbol_table
self._namespace: str | None = None
def set_namespace(self, namespace: str) -> None:
"""设置当前模块的命名空间"""
self._namespace = namespace
self._symtab.register_namespace(namespace)
def insert(self, module_symbols: ModuleSymbols) -> list[str]:
"""插入所有符号到主命名空间,返回已加载的符号名列表"""
loaded: list[str] = []
file_path: str = module_symbols.file_path
ns: dict[str, object] = self._symtab._namespaces.get(self._namespace, {}) if self._namespace else {}
# 插入类符号
for cls in module_symbols.classes:
# 枚举存储宽度("最宽成员类型")随条目登记:本条通路是跨模块符号表的
# 来源(.vpi/.pyi → LoadModuleSymbols),宽度必须一路带到序列化产物。
_enum_width: int | None = cls.enum_width if cls.type_kind == 'enum' else None
self._symtab._InsertClassSymbol(
cls.name, cls.type_kind, cls.lineno, file_path,
cls.members, cls.is_cpython_object, cls.is_packed,
EnumWidth=_enum_width
)
loaded.append(cls.name)
if self._namespace:
ns[cls.name] = self._symtab._symbols[cls.name]
# 插入枚举成员(短名 + 类名.成员名)—— CEnum 和 REnum 共用
if cls.type_kind in ('enum', 'renum'):
for member_name, member_value, member_lineno in cls.enum_members:
self._symtab._InsertEnumMemberSymbol(member_name, cls.name, member_lineno, file_path, value=member_value, EnumWidth=_enum_width)
loaded.append(member_name)
class_member_name: str = f"{cls.name}.{member_name}"
self._symtab._InsertEnumMemberSymbol(class_member_name, cls.name, member_lineno, file_path, value=member_value, EnumWidth=_enum_width)
loaded.append(class_member_name)
# REnum: 记录变体名列表到类符号(供 HandlesExprCall 跨模块变体构造识别)
if cls.type_kind == 'renum':
renum_info = self._symtab._symbols[cls.name]
renum_info.RenumVariants = [m[0] for m in cls.enum_members]
# 插入 typedef 符号
for td in module_symbols.typedefs:
self._symtab._InsertTypedefSymbol(
td.name, td.original_type_kind, td.original_class,
td.lineno, file_path, td.members
)
loaded.append(td.name)
if self._namespace:
ns[td.name] = self._symtab._symbols[td.name]
# 插入函数符号
for func in module_symbols.functions:
# 优先使用 CTypeInfo(保留符号性),回退到 LLVM 类型字符串
ret_type = func.ret_ctype if func.ret_ctype else func.ret_type
self._symtab._InsertFuncSymbol(
func.name, ret_type, func.param_types,
func.lineno, file_path, func.is_variadic, func.is_inline
)
loaded.append(func.name)
if self._namespace:
ns[func.name] = self._symtab._symbols[func.name]
# 插入 define 符号
for define in module_symbols.defines:
self._symtab._InsertDefineSymbol(
define.name, define.value, define.lineno, file_path
)
loaded.append(define.name)
if self._namespace:
ns[define.name] = self._symtab._symbols[define.name]
# 插入匿名类型符号(短名)
for anon_name, anon_data in module_symbols.anonymous_types.items():
self._symtab._InsertAnonymousSymbol(
anon_name, anon_data.is_union, anon_data.members,
anon_data.lineno, file_path
)
return loaded