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 口径等历史改动一并入库
This commit is contained in:
1 parent
53a345a59a
commit
c83fc752c6
53 files changed
+6238
-887
No files matched your search
@@ -10,7 +10,8 @@ from lib.includes import t
|
||||
from lib.includes.t import CTypeRegistry
|
||||
from lib.core.SymbolUtils import (
|
||||
IsListAnnotation, AnnotationContainsName, IsCPtrSubscriptNode, IsCPtrNode,
|
||||
IsRawPtrSubscriptNode, IsPtrSubscriptNode, ResolveGenericTypeArgStr)
|
||||
IsRawPtrSubscriptNode, IsPtrSubscriptNode, ResolveGenericTypeArgStr,
|
||||
EnumClassIntWidth, ClassHasFuncLevelCVTable)
|
||||
|
||||
|
||||
class DeclarationGenerator:
|
||||
@@ -55,7 +56,9 @@ class DeclarationGenerator:
|
||||
t.configure_platform(self.target_triple)
|
||||
|
||||
def generate(self, pyi_content: str, src_path: str) -> str:
|
||||
tree: ast.Module = ast.parse(pyi_content)
|
||||
# 传 src_path:解析失败时报错/回退诊断才带得上来源(否则 vast 记为 <unknown>,
|
||||
# 既无法定位文件,也无法知道是哪份 .pyi 出问题)
|
||||
tree: ast.Module = ast.parse(pyi_content, src_path)
|
||||
|
||||
self._DefineConstants: dict[str, int | str] = {}
|
||||
self._pyi_tree = tree
|
||||
@@ -255,9 +258,17 @@ class DeclarationGenerator:
|
||||
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':
|
||||
return None
|
||||
VarType: str = self._get_type_str(node.annotation)
|
||||
if VarType.startswith('[0 x ') and node.value and isinstance(node.value, ast.List):
|
||||
if VarType.startswith('[0 x ') and node.value:
|
||||
elem_type: str = VarType[5:-1]
|
||||
actual_count: int = len(node.value.elts)
|
||||
actual_count: int = 0
|
||||
if isinstance(node.value, ast.List):
|
||||
actual_count = len(node.value.elts)
|
||||
elif isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):
|
||||
# 字符串字面量:与 HandlesBase.ParseArrayCount(:731-732) / HandlesAssign
|
||||
# 全局路径同口径(len(str)+1,含结尾 NUL)。此前只修 List 值 → CArray
|
||||
# 字符串全局的 stub 声明停留在 [0 x i8],与定义端 [N x i8] 长度不一致
|
||||
# (跨模块 type mismatch / llc 拒绝)。
|
||||
actual_count = len(node.value.value) + 1
|
||||
if actual_count > 0:
|
||||
VarType = f'[{actual_count} x {elem_type}]'
|
||||
return f'@{var_name} = external global {VarType}'
|
||||
@@ -350,6 +361,10 @@ class DeclarationGenerator:
|
||||
if is_enum:
|
||||
enum_values: dict[str, int] = {}
|
||||
next_value: int = 0
|
||||
# 枚举存储宽度 = 最宽成员类型(与定义端 HandlesClassDef / 跨模块读取端
|
||||
# 同一规则源 EnumClassIntWidth;此处无 SymbolTable,走 t 类名 / builtins /
|
||||
# 库 typedef 的表)。声明端的全局类型必须与定义端运行时常量同宽(ABI)。
|
||||
enum_width: int = EnumClassIntWidth(node.body)
|
||||
for item in node.body:
|
||||
if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
|
||||
var_name: str = item.target.id
|
||||
@@ -367,7 +382,7 @@ class DeclarationGenerator:
|
||||
enum_values[var_name] = next_value
|
||||
next_value += 1
|
||||
for var_name, value in enum_values.items():
|
||||
decls.append(f'@__config_{class_name}_{var_name} = external global i32')
|
||||
decls.append(f'@__config_{class_name}_{var_name} = external global i{enum_width}')
|
||||
return decls
|
||||
if is_renum:
|
||||
# REnum 布局: { i32 __tag, <max_variant_payload> }
|
||||
@@ -473,6 +488,14 @@ class DeclarationGenerator:
|
||||
# (@t.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:
|
||||
# 与 HandlesClassDef._resolve_class_flags / TPV _detect_vtable_status 的
|
||||
# `_has_any_func_cvtable` 分支逐条对齐(类级 NoVTable / 无真实父类)。
|
||||
# 必须在此同步:定义模块按 IsCVTable 在 struct 首部放 vptr,若 stub 不同步,
|
||||
# 跨模块使用该类的 struct 布局会比定义模块少一个字段 ⇒ 字段整体错位。
|
||||
if not is_cvtable and ClassHasFuncLevelCVTable(node):
|
||||
if is_novtable or not has_parent_class:
|
||||
is_cvtable = True
|
||||
base_has_vtable: bool = False
|
||||
for base in node.bases:
|
||||
base_name: str | None = None
|
||||
@@ -847,6 +870,7 @@ class DeclarationGenerator:
|
||||
if has_methods and not is_cpython_object:
|
||||
is_cpython_object = True
|
||||
base_has_vtable: bool = False
|
||||
has_real_parent: bool = False
|
||||
for base in node.bases:
|
||||
base_name: str | None = None
|
||||
if isinstance(base, ast.Attribute):
|
||||
@@ -859,6 +883,7 @@ class DeclarationGenerator:
|
||||
elif isinstance(base.value, ast.Name):
|
||||
base_name = base.value.id
|
||||
if base_name and not self._is_marker_base(base_name):
|
||||
has_real_parent = True
|
||||
_base_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:
|
||||
@@ -874,6 +899,11 @@ class DeclarationGenerator:
|
||||
base_has_vtable = True
|
||||
if base_has_vtable:
|
||||
break
|
||||
# 方法级 virtual 触发类级 vtable(与上方 _generate_class_decl 同一判据,
|
||||
# 保持在同一个类里两处口径一致;详见该处注释)
|
||||
if not is_cvtable and not base_has_vtable and ClassHasFuncLevelCVTable(node):
|
||||
if is_novtable or not has_real_parent:
|
||||
is_cvtable = True
|
||||
return has_methods and is_cvtable and not base_has_vtable and not is_novtable
|
||||
|
||||
def _FlattenInheritedDecl(self, cls_name: str, seen_cls: set, member_types: list[str],
|
||||
@@ -1156,7 +1186,7 @@ class DeclarationGenerator:
|
||||
return _dg_llvm
|
||||
_dg_node: ast.AST | None = None
|
||||
try:
|
||||
_dg_node = ast.parse(_dg_bv, mode='eval').body
|
||||
_dg_node = ast.parse(_dg_bv, '<DeclarationGenerator:type_expr>', mode='eval').body
|
||||
except Exception:
|
||||
_dg_node = None
|
||||
if _dg_node is not None:
|
||||
@@ -1291,11 +1321,13 @@ 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] 注解 → [count x elem_type]
|
||||
# 支持 t.CArray (ast.Attribute)、CArray/rawarray (ast.Name) 三种写法
|
||||
# 处理 t.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 逐点等价)
|
||||
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'))
|
||||
or (isinstance(annotation.value, ast.Name) and annotation.value.id in ('CArray', 'rawarray', 'array'))
|
||||
)
|
||||
if ValueIsCArray:
|
||||
SliceNode: ast.AST = annotation.slice
|
||||
@@ -1307,9 +1339,13 @@ 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]:与 t.CArray[elem_type, None] 语义统一为
|
||||
# "长度自动推导数组"。此处无初始化字面量可推导 → 与 ,None 分支同用
|
||||
# [0 x elem] 占位,真实长度由 _generate_global_decl 按初始化字面量
|
||||
# (List 长度 / str 长度+1) 修正。
|
||||
# 参数位置经 _decay_array_to_ptr(:23-28) 退化为 elem*,与旧指针行为一致。
|
||||
ElemType: str = self._get_type_str(SliceNode, embedded=True)
|
||||
return f'{ElemType}*'
|
||||
return f'[0 x {ElemType}]'
|
||||
if isinstance(annotation.value, ast.Name) and annotation.value.id == 'tuple':
|
||||
slice_node: ast.AST = annotation.slice
|
||||
elem_types: list[str]
|
||||
|
||||
Reference in new issue
Block a user