fix(tpc): 跨模块模块级变量类登记与 Mod.Var.Field 链解析;并停止跟踪 __pycache__/*.pyc
This commit is contained in:
1 parent
9257dd841f
commit
015fbf17cf
100 files changed
+237
-1
No files matched your search
@@ -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):
|
||||
|
||||
Reference in new issue
Block a user