修正了 TPC 的一些错误,包括 Test 维护后 TPV 无法重新编译或重编译后越界的部分问题
This commit is contained in:
@@ -220,6 +220,11 @@ class ClassHandle(BaseHandle):
|
||||
Gen.global_vars = saved_global_vars
|
||||
self.Trans.VarScopes = saved_var_scopes
|
||||
Gen._generic_class_specializations[spec_key] = (spec_name, declare_only)
|
||||
# 缓存 type_args/type_names,供后续 declare_only=False 完整特化补发方法体使用
|
||||
# (如 _HandleMethodCallLlvm 中发现方法未定义时触发)
|
||||
if not hasattr(Gen, '_generic_class_spec_type_info'):
|
||||
Gen._generic_class_spec_type_info = {}
|
||||
Gen._generic_class_spec_type_info[spec_key] = (list(type_args), list(type_names) if type_names else None)
|
||||
if not hasattr(self.Trans, '_generic_class_specializations'):
|
||||
self.Trans._generic_class_specializations = {}
|
||||
self.Trans._generic_class_specializations[spec_key] = spec_name
|
||||
@@ -535,33 +540,50 @@ class ClassHandle(BaseHandle):
|
||||
if pm_name in parent_defaults:
|
||||
Gen.class_member_defaults[ClassName][pm_name] = parent_defaults[pm_name]
|
||||
Gen.class_members[ClassName] = inherited + Gen.class_members[ClassName]
|
||||
if ParentClass in Gen.class_methods:
|
||||
parent_methods: list = list(Gen.class_methods[ParentClass])
|
||||
# 构建子类已有方法映射(方法短名 -> 方法全名)
|
||||
child_method_map: dict[str, str] = {}
|
||||
for m in Gen.class_methods[ClassName]:
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
child_method_map[method_name] = m
|
||||
# 父类方法在前(保证 vtable 布局一致性,子类多态分派索引正确),
|
||||
# 子类新增方法在后。子类覆盖的方法放在父类方法的位置(用子类实现)。
|
||||
new_methods: list = []
|
||||
covered_names: set[str] = set()
|
||||
for pm in parent_methods:
|
||||
method_name: str = pm.split('.')[-1] if '.' in pm else pm
|
||||
if method_name in child_method_map:
|
||||
# 子类覆盖了父类方法 — 用子类的实现,放在父类的位置
|
||||
new_methods.append(child_method_map[method_name])
|
||||
covered_names.add(method_name)
|
||||
else:
|
||||
# 父类独有方法 — 子类未覆盖,注册子类包装器
|
||||
child_method: str = f"{ClassName}.{method_name}"
|
||||
new_methods.append(child_method)
|
||||
Gen.register_method(ClassName, child_method)
|
||||
# 添加子类新增方法(不在父类中的)
|
||||
for m in Gen.class_methods[ClassName]:
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
if method_name not in covered_names:
|
||||
new_methods.append(m)
|
||||
if ParentClass in Gen.class_methods:
|
||||
parent_methods: list = list(Gen.class_methods[ParentClass])
|
||||
# 从 Node.body 收集子类自有方法(此时 Gen.class_methods[ClassName] 可能为空,
|
||||
# 因为自有方法在 L660-676 才注册。若直接用 Gen.class_methods[ClassName],
|
||||
# child_method_map 会为空,所有父类方法被当作"未覆盖"添加为包装器,
|
||||
# 然后 register_method 又把它们追加到 Gen.class_methods[ClassName],
|
||||
# L566 循环再次添加 → 产生重复条目,vtable 布局与导入模块不一致)
|
||||
child_method_map: dict[str, str] = {}
|
||||
child_self_methods_snapshot: list[str] = []
|
||||
for _item in Node.body:
|
||||
if isinstance(_item, ast.FunctionDef):
|
||||
_mname: str = _item.name
|
||||
if _mname in ('__new__', '__init__', '__before_init__'):
|
||||
continue
|
||||
_item_meta: FuncMeta = self.Trans.FunctionHandler._ExtractFuncMeta(_item.decorator_list)
|
||||
if FuncMeta.PROPERTY_SETTER in _item_meta:
|
||||
_full: str = f"{ClassName}.{_mname}$set"
|
||||
elif FuncMeta.PROPERTY_DELETER in _item_meta:
|
||||
_full = f"{ClassName}.{_mname}$del"
|
||||
else:
|
||||
_full = f"{ClassName}.{_mname}"
|
||||
_short: str = _mname
|
||||
child_method_map[_short] = _full
|
||||
child_self_methods_snapshot.append(_full)
|
||||
# 父类方法在前(保证 vtable 布局一致性,子类多态分派索引正确),
|
||||
# 子类新增方法在后。子类覆盖的方法放在父类方法的位置(用子类实现)。
|
||||
new_methods: list = []
|
||||
covered_names: set[str] = set()
|
||||
for pm in parent_methods:
|
||||
method_name: str = pm.split('.')[-1] if '.' in pm else pm
|
||||
if method_name in child_method_map:
|
||||
# 子类覆盖了父类方法 — 用子类的实现,放在父类的位置
|
||||
new_methods.append(child_method_map[method_name])
|
||||
covered_names.add(method_name)
|
||||
else:
|
||||
# 父类独有方法 — 子类未覆盖,注册子类包装器
|
||||
child_method: str = f"{ClassName}.{method_name}"
|
||||
new_methods.append(child_method)
|
||||
Gen.register_method(ClassName, child_method)
|
||||
# 添加子类新增方法(不在父类中的)— 使用快照避免 register_method 污染
|
||||
for m in child_self_methods_snapshot:
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
if method_name not in covered_names:
|
||||
new_methods.append(m)
|
||||
Gen.class_methods[ClassName] = new_methods
|
||||
# 提取首个裸字符串字面量作为结构体 __doc__ docstring
|
||||
if (Node.body and isinstance(Node.body[0], ast.Expr)
|
||||
@@ -609,6 +631,19 @@ class ClassHandle(BaseHandle):
|
||||
if ClassName not in Gen.class_member_element_class:
|
||||
Gen.class_member_element_class[ClassName] = {}
|
||||
Gen.class_member_element_class[ClassName][VarName] = element_class
|
||||
# 泛型特化结构体指针字段(如 GSList[BasicBlock] | t.CPtr):
|
||||
# 记录特化名,供后续 _try_access_opaque_generic_member 在所有候选特化版本
|
||||
# 都有目标字段(如 Head/Tail/Count)时选择正确特化版本。
|
||||
# 现有 i8* 分支不覆盖结构体指针字段,这里补充。
|
||||
elif (isinstance(MemberType, ir.PointerType)
|
||||
and isinstance(MemberType.pointee, ir.IdentifiedStructType)
|
||||
and isinstance(item.annotation, ast.BinOp)
|
||||
and isinstance(item.annotation.op, ast.BitOr)):
|
||||
spec_in_anno: str | None = FindStructNameInAnnotation(item.annotation, Gen.structs)
|
||||
if spec_in_anno and '[' in spec_in_anno:
|
||||
if ClassName not in Gen.class_member_element_class:
|
||||
Gen.class_member_element_class[ClassName] = {}
|
||||
Gen.class_member_element_class[ClassName][VarName] = spec_in_anno
|
||||
if hasattr(TypeInfo.BaseType, 'IsSigned'):
|
||||
Gen.class_member_signeds[ClassName][VarName] = TypeInfo.BaseType.IsSigned
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user