diff --git a/lib/core/TypeAnnotationResolver.py b/lib/core/TypeAnnotationResolver.py index a6a8724..ec526e3 100644 --- a/lib/core/TypeAnnotationResolver.py +++ b/lib/core/TypeAnnotationResolver.py @@ -425,6 +425,54 @@ class TypeAnnotationResolver: TypeName: str = Node.value return TypeAnnotationResolver.from_type_name(TypeName) + @staticmethod + def _RecoverTypeFromNamespaces(TypeName: str, SymbolTable: dict | SymbolTable) -> CTypeInfo | None: + """平坦条目不是"类型"时,按命名空间找回同名**类型**条目(找不到 → None)。 + + 与 LLVMTypeMapper._resolve_name 的"同名冲突:平坦条目被 define / 枚举成员 / + 函数占位时找回类型"逐分支同构(同一条规则源):优先 typedef,其次结构体 + (struct / renum / exception 均置 IsStruct),再次枚举。 + + 必要性:平坦表(无前缀)一个名字只留一个条目,而 `import path as X` 的**模块 + 别名**与模块内 `class X` 同名(TransPyV 的 Generator 47 个 `rawptr[X.X]` 字段 + 全是这种形态)。条目被别名占住时,本解析器返回"无基类型"的空 CTypeInfo ⇒ + `rawptr[X.X]` 退化成 void 指针链(i8*/i8**),而 stub 声明侧是 + `%".X"*` ⇒ struct 布局里该槽被 set_body 冻结成 i8**(不可重设), + 赋值时报"指针隐式转换已禁止(层数不同)"。 + """ + _Namespaces: Any = getattr(SymbolTable, '_namespaces', None) + if not isinstance(_Namespaces, dict): + return None + for _NsSyms in _Namespaces.values(): + if not isinstance(_NsSyms, dict): + continue + _Cand: Any = _NsSyms.get(TypeName) + if _Cand is None: + continue + if getattr(_Cand, 'IsTypedef', False): + _R: CTypeInfo = _Cand.Copy() + _R.IsTypedef = True + if _R.BaseType is None: + _R.BaseType = t._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`)**逐字同口径**: + # 类引用不额外加指针层(PtrCount 保持 0)——本文件里 `rawptr[X]` 的层数 + # 由 rawptr 分支自己 +1,若此处再加一层会得到 `X**`。 + _R = CTypeInfo() + _R.BaseType = t.CStruct(name=TypeName) + _R.IsStruct = True + _R.Name = TypeName + return _R + if getattr(_Cand, 'IsEnum', False): + _R = CTypeInfo() + _R.BaseType = t.CInt() + _R.IsEnum = True + _R.Name = TypeName + return _R + return None + @staticmethod def _from_node_name(Node: ast.Name, SymbolTable: dict | SymbolTable) -> CTypeInfo: """处理 ast.Name 节点""" @@ -538,6 +586,18 @@ class TypeAnnotationResolver: if Entry.BaseType is None and (Entry.IsStruct or Entry.Name): Entry.BaseType = t.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): + # 平坦条目不是"类型"(同名**模块别名** / 函数 / 变量 / define / + # 枚举成员占住裸名):直接 return Entry 会得到"无基类型"的空 + # CTypeInfo ⇒ `rawptr[X]` 之类注解退化成 void 指针链 + # (i8*/i8**),struct 布局里该槽被 set_body 永久冻结。 + # 与上方 _from_node_attribute 及 LLVMTypeMapper._resolve_name + # 的"同名冲突找回类型"同一条规则源。 + _RecoveredName: CTypeInfo | None = TypeAnnotationResolver._RecoverTypeFromNamespaces( + TypeName, SymbolTable) + if _RecoveredName is not None: + return _RecoveredName return Entry elif isinstance(Entry, dict): if Entry.get('type') == 'typedef': @@ -1088,7 +1148,24 @@ class TypeAnnotationResolver: if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name): Result.BaseType = t.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): + # 平坦条目不是"类型"(同名**模块别名** / 函数 / 变量 / define / + # 枚举成员占住了裸名):Copy 得到的是"无基类型"的空 CTypeInfo ⇒ + # `rawptr[Mod.Cls]` 之类注解退化成 void 指针链(i8*/i8**), + # struct 布局里该槽被 set_body 永久冻结(现场:Generator 的 + # ExprGenFstr 槽 = i8**,而声明槽是 %"…ExprGenFstr"*,赋值时报 + # "层数不同")。与 LLVMTypeMapper._resolve_name 的"同名冲突找回 + # 类型"同一条规则源:按命名空间找回同名 typedef/结构体/枚举。 + _Recovered: CTypeInfo | None = TypeAnnotationResolver._RecoverTypeFromNamespaces( + TypeName, SymbolTable) + if _Recovered is not None: + return _Recovered return Result + _Recovered2: CTypeInfo | None = TypeAnnotationResolver._RecoverTypeFromNamespaces( + TypeName, SymbolTable) + if _Recovered2 is not None: + return _Recovered2 return CTypeInfo() if FullName in SymbolTable: