feat(codegen): 单目 & 支持对构造调用/函数调用结果取址
与 TransPyV 侧 ExprGenOps._addrof_of_call 同口径:复用 _HandleUnaryOpLlvm 已求值的 OperandVal;构造调用 _HandleClassNewLlvm 返回临时对象的 Ptr(Struct),原样返回;其它类型落到 allocaEntry 临时槽。避免二次求值导致 __before_init__/__init__ 跑两遍。
This commit is contained in:
1 parent
ae02431dd2
commit
5825e7e000
1 file changed
+18
-1
@@ -288,9 +288,26 @@ class ExprOpsHandle(BaseHandle):
|
||||
SubPtr: ir.Value | None = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Node.operand)
|
||||
if SubPtr and isinstance(SubPtr.type, ir.PointerType):
|
||||
return SubPtr
|
||||
elif isinstance(Node.operand, ast.Call):
|
||||
# &<call>() → rvalue 取址。复用上面已求值的 OperandVal,绝不二次求值
|
||||
# (构造调用会再跑一遍 __before_init__/__init__)。
|
||||
# · 构造调用(_HandleClassNewLlvm)返回的就是临时对象的栈存储指针
|
||||
# Ptr(Struct) —— 该指针即"栈构造结构体的地址"本身,原样返回;
|
||||
# 不能再套 alloca+store(会得到 Ptr(Ptr(Struct)),赋值端还得
|
||||
# load 一次回落,语义也从"对象地址"变"槽地址")。
|
||||
# · 其它返回值(标量、按值返回的结构体值):入口临时槽承载——
|
||||
# allocaEntry 同类型槽 → store → 返回槽地址(与 TransPyV 侧
|
||||
# ExprGenOps._addrof_of_call 同口径)。
|
||||
OperandType: ir.Type = OperandVal.type
|
||||
if isinstance(OperandType, ir.PointerType) \
|
||||
and isinstance(OperandType.pointee, (ir.IdentifiedStructType, ir.LiteralStructType)):
|
||||
return OperandVal
|
||||
TmpSlot: ir.Value = Gen._allocaEntry(OperandType, name="addrof_tmp")
|
||||
Gen.builder.store(OperandVal, TmpSlot)
|
||||
return TmpSlot
|
||||
raise TypeError(
|
||||
f"[fast-fail] 单目 '&' 取地址的操作数必须是左值"
|
||||
f"(Name/Attribute/Subscript),实际为 {type(Node.operand).__name__}"
|
||||
f"(Name/Attribute/Subscript)或构造调用/函数调用结果,实际为 {type(Node.operand).__name__}"
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
Reference in new issue
Block a user