refactor(c): 删除 c.* 及对应的裸名语法糖处理分支
移除 c.CIf 判断、Addr/Load/Deref/DerefAs/PtrToInt 裸名分支及 _HandleC* 处理函数;c. 前缀退役后不再保留任何处理路径。
This commit is contained in:
1 parent
f32235274b
commit
c94cdd7174
3 files changed
-228
No files matched your search
@@ -536,16 +536,6 @@ class ExprCallHandle(BaseHandle):
|
||||
# CPragma / CUndef 不是普通函数,优先于符号查找。
|
||||
if FuncName == 'Asm':
|
||||
return self.Trans.ExprAsmHandle._HandleAsmLlvm(Node)
|
||||
if FuncName == 'Addr':
|
||||
return self.Trans.CSpecialCallHandle._HandleCAddrLlvm(Node)
|
||||
if FuncName == 'Load':
|
||||
return self.Trans.CSpecialCallHandle._HandleCLoadLlvm(Node)
|
||||
if FuncName == 'Deref':
|
||||
return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node)
|
||||
if FuncName == 'DerefAs':
|
||||
return self._HandleCDerefAsLlvm(Node)
|
||||
if FuncName == 'PtrToInt':
|
||||
return self.Trans.CSpecialCallHandle._HandleCPtrToIntLlvm(Node)
|
||||
if FuncName in ('AsmInp', 'AsmOut', 'LInp', 'LOut'):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if FuncName == 'LLVMIR':
|
||||
@@ -4850,47 +4840,6 @@ class ExprCallHandle(BaseHandle):
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
|
||||
def _HandleCDerefAsLlvm(self, Node: ast.Call) -> ir.Value | None:
|
||||
"""DerefAs(p, v):bitcast **指针** p 到 typeof(v)* 后按值存 v(`*(T*(p)) = v`)。
|
||||
|
||||
与 ViperC CallGenCBuiltin.translate_c_derefas 逐字同口径:
|
||||
- 单参形式(len<2)是**解引用读取**(等同 Deref(p));
|
||||
- 双参:p、v 均为指针且 p 的 pointee 是结构体且与 v 的 pointee **同一**时,
|
||||
按整对象拷贝(load v 指向的对象 + bitcast p + store);否则 bitcast p 到
|
||||
typeof(v)* 后按值 store v。
|
||||
此前实现把**值** bitcast 成指针大小整数再写(`*(intptr_t*(p)) = (intptr_t)v`),
|
||||
与语义不符(R5 混淆了"bitcast 指针"与"bitcast 值")。
|
||||
"""
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
if Node.args is None or len(Node.args) < 1:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if len(Node.args) < 2:
|
||||
# 单参:解引用读取(与 VPC translate_c_derefas 的转发口径一致)
|
||||
return self.Trans.CSpecialCallHandle._HandleCDerefLlvm(Node)
|
||||
ptr_val: ir.Value | None = self.HandleExprLlvm(Node.args[0])
|
||||
val_val: ir.Value | None = self.HandleExprLlvm(Node.args[1])
|
||||
if ptr_val is None or val_val is None:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if not isinstance(ptr_val.type, ir.PointerType):
|
||||
return val_val
|
||||
# 整对象拷贝:p 的 pointee 是结构体且与 v 的 pointee 同一(REnum 变体 tag 才不会丢)
|
||||
if isinstance(val_val.type, ir.PointerType):
|
||||
p_pointee: ir.Type = ptr_val.type.pointee
|
||||
v_pointee: ir.Type = val_val.type.pointee
|
||||
if (isinstance(p_pointee, (ir.IdentifiedStructType, ir.LiteralStructType))
|
||||
and p_pointee == v_pointee):
|
||||
loaded_s: ir.Value = Gen._load(val_val, name="deref_as_struct_load")
|
||||
store_ptr: ir.Value = ptr_val
|
||||
if store_ptr.type != val_val.type:
|
||||
store_ptr = Gen.builder.bitcast(ptr_val, val_val.type, name="deref_as_ptr_align")
|
||||
Gen._store(loaded_s, store_ptr)
|
||||
return val_val
|
||||
# 常规:bitcast p 到 typeof(v)* 后按值存 v(`*(T*(p)) = v`)
|
||||
if ptr_val.type.pointee != val_val.type:
|
||||
ptr_val = Gen.builder.bitcast(ptr_val, ir.PointerType(val_val.type), name="deref_as_cast")
|
||||
Gen._store(val_val, ptr_val)
|
||||
return val_val
|
||||
|
||||
def _InjectRequiresFields(self, result: ir.Value, ClassName: str, Gen: LlvmGeneratorMixin) -> None:
|
||||
"""在 __new__ 后、__init__ 前自动注入 __requires__/__require_must__ 字段。
|
||||
|
||||
|
||||
@@ -30,14 +30,6 @@ class IfHandle(BaseHandle):
|
||||
if isinstance(node, ast.Call):
|
||||
if isinstance(node.func, ast.Name):
|
||||
return node.func.id in ('@CIf', '@CIfdef', '@CIfndef')
|
||||
if (isinstance(node.func, ast.Attribute)
|
||||
and isinstance(node.func.value, ast.Name)
|
||||
and node.func.value.id == 'c'
|
||||
and node.func.attr in ('CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif')):
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError
|
||||
raise FailFastError(
|
||||
f"`c.{node.func.attr}` 不是内建标记:cif/celif 条件请使用 "
|
||||
f"`cif` / `celif` 语句与 `defined(NAME)` 谓词")
|
||||
return False
|
||||
|
||||
def _resolve_macro_name(self, arg: ast.expr) -> str | None:
|
||||
|
||||
@@ -12,83 +12,6 @@ from lib.constants.config import mode as _config_mode
|
||||
|
||||
|
||||
class CSpecialCallHandle(BaseHandle):
|
||||
def _HandleCAddrLlvm(self, Node: ast.Call) -> ir.Value:
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
if not Node.args:
|
||||
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
||||
Arg = Node.args[0]
|
||||
if isinstance(Arg, ast.Call):
|
||||
ClassName = None
|
||||
if isinstance(Arg.func, ast.Name):
|
||||
ClassName = Arg.func.id
|
||||
elif isinstance(Arg.func, ast.Attribute):
|
||||
ClassName = Arg.func.attr
|
||||
if ClassName and ClassName in Gen.structs:
|
||||
StructType = Gen.structs[ClassName]
|
||||
if isinstance(StructType, ir.PointerType):
|
||||
StructType = StructType.pointee
|
||||
ObjPtr = Gen._allocaEntry(StructType, name=f"{ClassName}_obj")
|
||||
zero_val = Gen._zero_value_for_type(StructType)
|
||||
if zero_val is not None:
|
||||
Gen.builder.store(zero_val, ObjPtr)
|
||||
ConstructorName = f"{ClassName}.__init__"
|
||||
if ConstructorName in Gen.functions:
|
||||
func = Gen.functions[ConstructorName]
|
||||
InitArgs = [ObjPtr]
|
||||
for carg in Arg.args:
|
||||
ArgVal = self.HandleExprLlvm(carg)
|
||||
if ArgVal:
|
||||
InitArgs.append(ArgVal)
|
||||
for kw in Arg.keywords:
|
||||
ArgVal = self.HandleExprLlvm(kw.value)
|
||||
if ArgVal:
|
||||
InitArgs.append(ArgVal)
|
||||
if hasattr(self.Trans.ExprCallHandle, '_append_eh_msg_out_arg'):
|
||||
self.Trans.ExprCallHandle._append_eh_msg_out_arg(InitArgs, func, Gen)
|
||||
adjusted = Gen._adjust_args(InitArgs, func)
|
||||
Gen.builder.call(func, adjusted, name=f"{ClassName}_construct")
|
||||
return Gen.builder.bitcast(ObjPtr, ir.IntType(8).as_pointer(), name=f"{ClassName}_as_i8ptr")
|
||||
if isinstance(Arg, ast.Subscript):
|
||||
SubPtr = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Arg)
|
||||
if SubPtr and isinstance(SubPtr.type, ir.PointerType):
|
||||
return Gen.builder.bitcast(SubPtr, ir.IntType(8).as_pointer(), name="addr_subscript_as_i8ptr")
|
||||
if isinstance(Arg, ast.Attribute):
|
||||
AttrPtr = self.Trans.ExprAttrHandle._get_attr_ptr(Arg)
|
||||
if AttrPtr and isinstance(AttrPtr.type, ir.PointerType):
|
||||
return Gen.builder.bitcast(AttrPtr, ir.IntType(8).as_pointer(), name="addr_attr_as_i8ptr")
|
||||
if isinstance(Arg, ast.Name):
|
||||
VarName = Arg.id
|
||||
if VarName in Gen.functions:
|
||||
func = Gen.functions[VarName]
|
||||
return Gen.builder.bitcast(func, ir.IntType(8).as_pointer(), name="addr_func_as_i8ptr")
|
||||
if VarName in Gen.variables and Gen.variables[VarName] is not None:
|
||||
var_ptr = Gen.variables[VarName]
|
||||
if isinstance(var_ptr.type, ir.PointerType):
|
||||
# For pointer-to-pointer allocas (var_ptr is T**):
|
||||
# - If T is a named struct (@Object class), the variable semantically
|
||||
# IS the struct, so Addr should return the struct pointer value.
|
||||
# - If T is a primitive pointer type (e.g., i8*), the variable semantically
|
||||
# holds a pointer, so Addr should return &var (alloca address).
|
||||
if isinstance(var_ptr.type.pointee, ir.PointerType):
|
||||
pointee = var_ptr.type.pointee.pointee
|
||||
if isinstance(pointee, ir.IdentifiedStructType):
|
||||
# @Object class variable — return Loaded struct pointer
|
||||
ArgVal = self.HandleExprLlvm(Arg)
|
||||
if ArgVal and isinstance(ArgVal.type, ir.PointerType):
|
||||
return Gen.builder.bitcast(ArgVal, ir.IntType(8).as_pointer(), name="addr_as_i8ptr")
|
||||
# Pointer-type variable — return alloca address (&var)
|
||||
return Gen.builder.bitcast(var_ptr, ir.IntType(8).as_pointer(), name="addr_as_i8ptr")
|
||||
return Gen.builder.bitcast(var_ptr, ir.IntType(8).as_pointer(), name="addr_as_i8ptr")
|
||||
ArgVal = self.HandleExprLlvm(Arg)
|
||||
if ArgVal:
|
||||
if isinstance(ArgVal.type, ir.IntType):
|
||||
alloca = Gen._alloca(ArgVal.type, name="addr_tmp")
|
||||
Gen._store(ArgVal, alloca)
|
||||
return Gen.builder.bitcast(alloca, ir.IntType(8).as_pointer(), name="addr_as_i8ptr")
|
||||
elif isinstance(ArgVal.type, ir.PointerType):
|
||||
return Gen.builder.bitcast(ArgVal, ir.IntType(8).as_pointer(), name="addr_bitcast")
|
||||
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
||||
|
||||
def EmitRawCopyLlvm(self, DstPtr: ir.Value, SrcPtr: ir.Value, Gen: LlvmGeneratorMixin,
|
||||
NamePrefix: str = "rawcopy") -> bool:
|
||||
"""Emit `*dst = *src` as a raw byte copy (Load semantics); False if unusable.
|
||||
@@ -111,98 +34,6 @@ class CSpecialCallHandle(BaseHandle):
|
||||
Gen._store(Loaded, DstCast)
|
||||
return True
|
||||
|
||||
def _HandleCLoadLlvm(self, Node: ast.Call) -> ir.Value:
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
if len(Node.args) < 2:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
# Load(a, b) 语义: *a = *b(a 是目标,b 是源)
|
||||
# wiki 文档: Load(ptr, value) -> *ptr = *value;
|
||||
dst_val: ir.Value | None = self.HandleExprLlvm(Node.args[0])
|
||||
src_val: ir.Value | None = self.HandleExprLlvm(Node.args[1])
|
||||
if not src_val or not dst_val:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if not isinstance(src_val.type, ir.PointerType) or not isinstance(dst_val.type, ir.PointerType):
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
pointee = dst_val.type.pointee
|
||||
# Addr 统一返回 i8* 通用指针,丢失原始类型信息。
|
||||
# 若 dst 是 Addr(var),从 var 的 alloca 类型推断真实 pointee(如 i64),
|
||||
# 否则 Load 只会按 i8 加载 1 字节(IEEE 754 double→u64 位重解释 bug)。
|
||||
if (isinstance(pointee, ir.IntType) and pointee.width == 8
|
||||
and isinstance(Node.args[0], ast.Call)
|
||||
and isinstance(Node.args[0].func, ast.Name)
|
||||
and Node.args[0].func.id == 'Addr'
|
||||
and Node.args[0].args
|
||||
and isinstance(Node.args[0].args[0], ast.Name)):
|
||||
var_name = Node.args[0].args[0].id
|
||||
if var_name in Gen.variables and Gen.variables[var_name] is not None:
|
||||
var_ptr = Gen.variables[var_name]
|
||||
if isinstance(var_ptr.type, ir.PointerType):
|
||||
pointee = var_ptr.type.pointee
|
||||
TargetPtrTy: ir.PointerType = ir.PointerType(pointee)
|
||||
DstPtr: ir.Value = dst_val if dst_val.type == TargetPtrTy else Gen.builder.bitcast(dst_val, TargetPtrTy, name="cLoad_dst_cast")
|
||||
return ir.Constant(ir.IntType(32), 1 if self.EmitRawCopyLlvm(DstPtr, src_val, Gen, "cLoad") else 0)
|
||||
|
||||
def _HandleCDerefLlvm(self, Node: ast.Call) -> ir.Value:
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
if not Node.args:
|
||||
return ir.Constant(ir.IntType(64), 0)
|
||||
# 检测嵌套 Deref(Deref(...)):设置标志让内层 Deref 加载为指针
|
||||
IsNestedDeref: bool = (
|
||||
isinstance(Node.args[0], ast.Call)
|
||||
and isinstance(Node.args[0].func, ast.Name)
|
||||
and Node.args[0].func.id == 'Deref'
|
||||
)
|
||||
if IsNestedDeref:
|
||||
Gen._nested_deref_load_ptr = True
|
||||
try:
|
||||
arg_val: ir.Value | None = self.HandleExprLlvm(Node.args[0])
|
||||
finally:
|
||||
if IsNestedDeref:
|
||||
Gen._nested_deref_load_ptr = False
|
||||
if arg_val is None:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
if isinstance(arg_val.type, ir.PointerType):
|
||||
# 嵌套 Deref 的内层:加载为指针 (i8*),不推断目标类型
|
||||
# 因为结果会被外层 Deref 再次解引用
|
||||
NestedLoadPtr: bool = getattr(Gen, '_nested_deref_load_ptr', False)
|
||||
if NestedLoadPtr:
|
||||
PtrType: ir.Type = ir.PointerType(ir.IntType(8))
|
||||
casted: ir.Value = Gen.builder.bitcast(arg_val, ir.PointerType(PtrType), name="deref_cast")
|
||||
Loaded = Gen._load(casted, name="deref")
|
||||
if Loaded is not None:
|
||||
return Loaded
|
||||
# 读取宽度只由指针的 pointee 类型决定(_load 按 arg_val.type.pointee
|
||||
# 加载一个元素):pointee 是 i8(CPtr / void* / str / bytes)即恒读
|
||||
# 1 字节,不再按赋值目标注解反推宽度——那会让同一处 Deref(i8*) 的
|
||||
# 读取宽度取决于它是否恰好出现在带注解赋值的 RHS 里。需要 4/8 字节等
|
||||
# 更宽读取时,由调用点显式给出元素类型指针后再解引用
|
||||
# (Deref((int | CPtr)(p)) / Deref(CUInt64T(p, CPtr)))。
|
||||
Loaded = Gen._load(arg_val, name="deref")
|
||||
if Loaded is not None:
|
||||
return Loaded
|
||||
return arg_val
|
||||
|
||||
def _HandleCPtrToIntLlvm(self, Node: ast.Call) -> ir.Value:
|
||||
Gen: LlvmGeneratorMixin = self.Trans.LlvmGen
|
||||
if not Node.args:
|
||||
return ir.Constant(ir.IntType(64), 0)
|
||||
arg_val: ir.Value | None = self.HandleExprLlvm(Node.args[0])
|
||||
if arg_val is None:
|
||||
return ir.Constant(ir.IntType(64), 0)
|
||||
if isinstance(arg_val.type, ir.PointerType):
|
||||
return Gen.builder.ptrtoint(arg_val, ir.IntType(64), name="ptrtoint_result")
|
||||
if isinstance(arg_val.type, ir.IntType):
|
||||
if arg_val.type.width < 64:
|
||||
return Gen.builder.zext(arg_val, ir.IntType(64), name="zext_ptrtoint")
|
||||
elif arg_val.type.width > 64:
|
||||
return Gen.builder.trunc(arg_val, ir.IntType(64), name="trunc_ptrtoint")
|
||||
return arg_val
|
||||
return ir.Constant(ir.IntType(64), 0)
|
||||
|
||||
|
||||
class TSpecialCallHandle(BaseHandle):
|
||||
|
||||
@staticmethod
|
||||
def _ResolveTAttrToCName(attr: str) -> str | None:
|
||||
ctype_cls: type | None = CTypeRegistry.GetClassByName(attr)
|
||||
if ctype_cls is not None:
|
||||
|
||||
Reference in new issue
Block a user