fix(codegen): 指针强转基座 T*(x) 的字段写入补联合类名通道
与读取侧 _handle_attr_call_result 的联合分支同口径:_get_attr_ptr 新增 Call 基座分支,用 _extract_union_base_class 取裸类名后 bitcast/inttoptr 回 Ptr(类) 再 GEP 成员。此前写入侧只认 Name/Attribute/Subscript,强转基座的字段写入静默返回 None。
This commit is contained in:
1 parent
5825e7e000
commit
e33ac795ed
1 file changed
+29
@@ -1527,6 +1527,35 @@ class ExprAttrHandle(BaseHandle):
|
||||
if offset is not None:
|
||||
MemberPtr = Gen.builder.gep(SubPtr, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=Node.attr)
|
||||
return MemberPtr
|
||||
elif isinstance(Node.value, ast.Call):
|
||||
# 指针强转基座(`(ast.Call*(vinner)).IsVolatile = 1`):`T*(x)` 被 vast 的
|
||||
# _ConsumePtrSuffixCall 解析为 `(T | t.CPtr)(x)` 强转调用,结果类型是联合
|
||||
# 简化后的 i8*(struct 身份丢失),故须从强转注解(func 是 BitOr 联合)
|
||||
# 提真实类名,bitcast/inttoptr 回 Ptr(类) 后 GEP 成员。
|
||||
# 与读取侧 _handle_attr_call_result 的联合分支(_extract_union_base_class)
|
||||
# 逐字同口径;此前写入侧只认 Name/Attribute/Subscript,强转基座的字段
|
||||
# 写入一律静默返回 None。
|
||||
ObjVal: Any = self.HandleExprLlvm(Node.value)
|
||||
if ObjVal is not None and isinstance(Node.value.func, ast.BinOp) \
|
||||
and isinstance(Node.value.func.op, ast.BitOr):
|
||||
UnionCls: str | None = self._extract_union_base_class(Node.value.func)
|
||||
if UnionCls and UnionCls in Gen.structs:
|
||||
ST: Any = Gen.structs[UnionCls]
|
||||
if isinstance(ST, ir.IdentifiedStructType) and (ST.elements is None or len(ST.elements) == 0):
|
||||
self.Trans.ImportHandler._TryLoadStructFromStub(UnionCls, Gen)
|
||||
ST = Gen.structs.get(UnionCls, ST)
|
||||
TargetPtrTy: Any = ir.PointerType(ST)
|
||||
if isinstance(ObjVal.type, ir.PointerType):
|
||||
if ObjVal.type != TargetPtrTy:
|
||||
ObjVal = Gen.builder.bitcast(ObjVal, TargetPtrTy, name=f"cast_{UnionCls}")
|
||||
elif isinstance(ObjVal.type, ir.IntType):
|
||||
ObjVal = Gen.builder.inttoptr(ObjVal, TargetPtrTy, name=f"int2ptr_{UnionCls}")
|
||||
else:
|
||||
return None
|
||||
offset: int | None = Gen._get_member_offset(Node.attr, UnionCls)
|
||||
if offset is not None:
|
||||
MemberPtr = Gen.builder.gep(ObjVal, [ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), offset)], name=Node.attr)
|
||||
return MemberPtr
|
||||
return None
|
||||
|
||||
def _HandleSliceLlvm(self, base_val: ir.Value, slice_node: ast.Slice | ast.Index, base_ast: ast.AST) -> ir.Value | None:
|
||||
|
||||
Reference in new issue
Block a user