fix(tpc): 跨模块模块级变量类登记与 Mod.Var.Field 链解析;并停止跟踪 __pycache__/*.pyc

This commit is contained in:
TermiNexus committed 2026-09-12 11:51:42 +08:00
1 parent 9257dd841f
commit 015fbf17cf
100 files changed
+237 -1

No files matched your search

+90
View File
@@ -17,6 +17,15 @@ from lib.includes.t import CTypeRegistry
from lib.core.SymbolUtils import ParseListAnnotation, ExtractTypeNameFromBinOp, AnnotationContainsName, FindStructNameInAnnotation
# 注解里的存储类 / 限定符标记:这些名字**不是类名**(联合注解里与指针类混写,
# 如 `t.CExtern | rowptr[CompilerFactory]`),提取"指针指向的类"时必须滤掉。
_MARKER_ANNOT_NAMES: frozenset[str] = frozenset({
'CExtern', 'CExport', 'CStatic', 'CInline', 'CConst', 'CVolatile', 'CRegister',
'CAuto', 'CDefine', 'CTypedef', 'CPostdefinition', 'CPtr', 'CArrayPtr', 'CVoid',
'State', 'TLS',
})
class ImportHandle(BaseHandle):
_struct_Load_cache = {}
_pyi_cache = {}
@@ -848,6 +857,67 @@ class ImportHandle(BaseHandle):
if module_name:
self._LoadDeclarationsFromStubLlvm(module_name, Gen)
def _AnnotationStructName(self, annotation: ast.AST) -> str | None:
"""从注解里提取「指针指向的类」短名(递归,0 判定返回 None)
覆盖形态:`X` / `mod.X` / `rowptr[X]` / `t.CPtr[X]` / 联合 `A | B`(两翼都试)。
存储类与限定符标记(`t.CExtern` / `t.CExport` / `t.CPtr` 等)不算类名,
由 `_MARKER_ANNOT_NAMES` 过滤;返回的是**短名**,调用方再解析成
`Gen.structs` 真实键。
"""
if annotation is None:
return None
if isinstance(annotation, ast.BinOp) and isinstance(annotation.op, ast.BitOr):
_left: str | None = self._AnnotationStructName(annotation.left)
if _left:
return _left
return self._AnnotationStructName(annotation.right)
if isinstance(annotation, ast.Subscript):
_base: ast.AST = annotation.value
_bn: str = ''
if isinstance(_base, ast.Name):
_bn = _base.id
elif isinstance(_base, ast.Attribute):
_bn = _base.attr
if _bn in ('rowptr', 'CPtr', 'CArrayPtr'):
_sl: ast.AST = annotation.slice
if hasattr(ast, 'Index') and isinstance(_sl, ast.Index):
_sl = _sl.value
return self._AnnotationStructName(_sl)
return None
if isinstance(annotation, ast.Name):
if annotation.id in _MARKER_ANNOT_NAMES:
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
if annotation.attr in _MARKER_ANNOT_NAMES:
return None
return annotation.attr
return None
def _ResolveAnnotationStructKey(self, Gen: LlvmGeneratorMixin, name: str) -> str | None:
"""把注解里的类短名解析为 `Gen.structs` 的真实键(0 命中返回 None)
三条路径与类字段侧的 `rowptr[裸结构]` 登记保持一致:裸名直查 /
`class_sha1_map` 加前缀 / 全量短名模糊扫描(跨模块类在
`class_sha1_map` 尚未登记该短名时靠这条兜住)。
"""
if not name:
return None
if name in Gen.structs:
return name
_sha: str | None = (getattr(Gen, 'class_sha1_map', {}) or {}).get(name)
if _sha and f'{_sha}.{name}' in Gen.structs:
return f'{_sha}.{name}'
for _k in Gen.structs:
_short: str = _k.split('.')[-1] if '.' in _k else _k
if _short == name:
return _k
return None
def _EmitExternalGlobalDeclLlvm(self, Node: ast.AnnAssign | ast.Assign, Gen: LlvmGeneratorMixin, module_name: str | None = None, ModulePath: str | None = None) -> None:
"""Emit external global variable declaration from imported module"""
if isinstance(Node, ast.AnnAssign) and isinstance(Node.target, ast.Name):
@@ -857,6 +927,26 @@ class ImportHandle(BaseHandle):
IsPtr = False
is_string_val = False
TypeInfo = None
# 【跨模块模块级变量的**类登记**】`CTypeInfo.FromNode` 对
# `X | t.CPtr` / `rowptr[X]` 注解只给出指针占位(rowptr[X] 折叠成 i8*),
# 且本函数**只算类型、不登记变量类** → 消费侧 `Mod.Var.Field` 链在
# `_get_var_class` 里解析为空:StructGenMixin.vp:139 "属性访问未能解析出
# 目标类型/成员"、CallGenLeafKit.vp:589 / ClassGenVTable.vp:99 误报
# Unknown module(factory.PermPool.alloc)。这里对齐 HandlesAnnAssign
# 变量侧补偿:从注解找回真实结构体键并登记;仅当缺失或指针占位时覆盖。
# 注意:必须放在下面的「已存在则 return」**之前**,否则全局量先由别的
# 路径声明(如 stub 文本 i8*)时这里永远不执行。
_eg_tn: str | None = self._AnnotationStructName(Node.annotation)
if _eg_tn:
# 只在能落到 Gen.structs 真实键时登记(避免把 sizet/CPtr 等标量名当类)
_eg_tk: str | None = self._ResolveAnnotationStructKey(Gen, _eg_tn)
if _eg_tk:
_eg_cur: str | None = Gen.var_struct_class.get(VarName)
if (not _eg_cur or _eg_cur == 'rowptr' or _eg_cur.endswith('.rowptr')
or _eg_cur.startswith('rowptr[')):
Gen.var_struct_class[VarName] = _eg_tk
if getattr(Gen, 'global_struct_class', None) is not None:
Gen.global_struct_class[VarName] = _eg_tk
if VarName in Gen.module.globals:
existing = Gen.module.globals[VarName]
if isinstance(existing, ir.GlobalVariable):