refactor(return): 移除 @c.CReturn 多返回值处理器,只保留 -> tuple[ty1, ty2, ...],遇到 CReturn 一律报错

DeclarationGenerator:tuple[...] 分支逐字保留(仅 CReturnTypes 机械改名 MultiRetTypes),装饰器分支改为 SyntaxError,报文含函数名与“请改用 -> tuple[ty1, ty2, ...]”提示

HandlesAssign(a, b = f() 解包路径):删除装饰器收集分支并改为报错;tuple[...] 恢复与逐个解包逻辑逐字不变

HandlesFunctions:新增 _CRETURN_REMOVED_HINT 与 _RejectCReturnDecorator,在函数定义入口(_GetFunctionSignatureLlvm / _EmitFunctionLlvm)fail-fast——即使只有装饰器、没有 -> 注解,也不会让返回类型静默退化成 i32

HandlesImports:外部函数声明处同样报错,并删除下游已失效的 CReturnTypes 参数拼接死代码

HandlesReturn / HandlesFor / BaseTranslator:CurrentCReturnTypes 等机械改名(读写端一致,无行为变化)

includes/c.py:保留 CReturn 名字作墓碑(删掉会让 @c.CReturn 变成未知属性、可能被静默忽略),docstring 写明已移除并指路 -> tuple[...];README 措辞同步
This commit is contained in:
TermiNexus committed 2026-09-28 13:57:04 +08:00
1 parent e5a6616f8b
commit 35de6321f6
9 files changed
+96 -86

No files matched your search

+1 -1
View File
@@ -64,7 +64,7 @@ def main() -> CInt | CExport:
| [01-overview.md](wiki/01-overview.md) | 语言概述、两阶段编译流程、SHA1 命名空间、`t.CDefine`/`t.CExport`/`t.CInline` 深度解析 |
| [02-type-system.md](wiki/02-type-system.md) | 类型系统(基本类型、指针、数组、结构体、联合体、枚举、typedef、`__attribute__`) |
| [03-variables.md](wiki/03-variables.md) | 变量声明与赋值(含 `t.CDefine` 常量) |
| [04-functions.md](wiki/04-functions.md) | 函数定义与调用(含 `t.CExport`、`t.CInline`、`t.CDefine` 函数、`@c.CReturn`) |
| [04-functions.md](wiki/04-functions.md) | 函数定义与调用(含 `t.CExport`、`t.CInline`、`t.CDefine` 函数、`-> tuple[...]` 多返回值) |
| [05-classes.md](wiki/05-classes.md) | 类与数据布局(结构体、联合体、枚举、typedef、位域) |
| [06-oop.md](wiki/06-oop.md) | 面向对象与运算符重载(`@t.Object`、`@t.CVTable`、`@t.NoVTable`、继承、dunder 方法) |
| [07-control-flow.md](wiki/07-control-flow.md) | 控制流(条件、循环、match) |
+11 -7
View File
@@ -182,24 +182,28 @@ class DeclarationGenerator:
is_export: bool = self._is_export_func(node)
if self.module_sha1 and not is_export:
func_name = f"{self.module_sha1}.{func_name}"
CReturnTypes: list[ast.AST] = []
MultiRetTypes: list[ast.AST] = []
if node.decorator_list:
for decorator in node.decorator_list:
# fail-fast:`@c.CReturn` 装饰器已移除,任何地方出现都必须报错,
# 不得静默忽略或改写;多返回值请改用 `-> tuple[ty1, ty2, ...]`。
if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
if decorator.func.attr == 'CReturn':
for arg in decorator.args:
CReturnTypes.append(arg)
raise SyntaxError(
f"函数 '{node.name}':`@c.CReturn` 已移除:请改用返回注解 "
f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)"
)
if node.returns:
if isinstance(node.returns, ast.Subscript) and isinstance(node.returns.value, ast.Name) and node.returns.value.id == 'tuple':
slice_node: ast.AST = node.returns.slice
if isinstance(slice_node, ast.Tuple):
for elt in slice_node.elts:
CReturnTypes.append(elt)
MultiRetTypes.append(elt)
else:
CReturnTypes.append(slice_node)
MultiRetTypes.append(slice_node)
ret_type: str
if CReturnTypes:
elem_types: list[str] = [self._get_type_str(rt, embedded=True) for rt in CReturnTypes]
if MultiRetTypes:
elem_types: list[str] = [self._get_type_str(rt, embedded=True) for rt in MultiRetTypes]
ret_type = '{ ' + ', '.join(elem_types) + ' }'
else:
ret_type = self._get_type_str(node.returns)
+26 -22
View File
@@ -536,31 +536,35 @@ class AssignHandle(BaseHandle):
elif isinstance(Node.value.func, ast.Attribute):
FuncName = Node.value.func.attr
ModulePath = self.Trans.ExprCallHandle._get_ModulePath(Node.value.func.value)
CReturnTypes: list[ast.expr] = []
MultiRetTypes: list[ast.expr] = []
FuncDef: ast.FunctionDef | None = self.Trans.FunctionDefCache.get(FuncName) if FuncName else None
if FuncDef:
if FuncDef.returns and isinstance(FuncDef.returns, ast.Subscript):
if isinstance(FuncDef.returns.value, ast.Name) and FuncDef.returns.value.id == 'tuple':
slice_node: ast.expr = FuncDef.returns.slice
if isinstance(slice_node, ast.Tuple):
CReturnTypes = slice_node.elts
MultiRetTypes = slice_node.elts
else:
CReturnTypes = [slice_node]
MultiRetTypes = [slice_node]
if FuncDef.decorator_list:
for decorator in FuncDef.decorator_list:
if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
# fail-fast:`@c.CReturn` 已移除,扫到即报错。
if decorator.func.attr == 'CReturn':
for arg in decorator.args:
CReturnTypes.append(arg)
if not CReturnTypes and FuncName:
raise SyntaxError(
f"函数 '{FuncName}':`@c.CReturn` 已移除:请改用返回注解 "
f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)"
f"{Gen._get_node_info()}"
)
if not MultiRetTypes and FuncName:
func: ir.Function | None = Gen.functions.get(FuncName)
if func:
func_ft: ir.FunctionType | None = getattr(func, 'ftype', None)
if func_ft:
ret_type: ir.Type = func_ft.return_type
if isinstance(ret_type, ir.LiteralStructType):
CReturnTypes = [None] * len(ret_type.elements)
if not CReturnTypes:
MultiRetTypes = [None] * len(ret_type.elements)
if not MultiRetTypes:
sym_key: str = FuncName
if not self.Trans.SymbolTable.has(sym_key):
if ModulePath:
@@ -575,7 +579,7 @@ class AssignHandle(BaseHandle):
else:
ret_type = Gen._type_str_to_llvm(str(ret_type_info) if ret_type_info else 'i32', False)
if isinstance(ret_type, ir.LiteralStructType):
CReturnTypes = [None] * len(ret_type.elements)
MultiRetTypes = [None] * len(ret_type.elements)
if FuncName not in Gen.functions:
if isinstance(ret_type, ir.VoidType):
ret_type = ir.IntType(32)
@@ -593,18 +597,18 @@ class AssignHandle(BaseHandle):
func_decl: ir.Function = ir.Function(Gen.module, func_type, name=MangledName)
Gen.functions[MangledName] = func_decl
Gen.functions[FuncName] = func_decl
if not CReturnTypes and FuncName:
if not MultiRetTypes and FuncName:
func: ir.Function | None = Gen.functions.get(FuncName)
if func:
func_ft: ir.FunctionType | None = getattr(func, 'ftype', None)
if func_ft:
ret_type: ir.Type = func_ft.return_type
if isinstance(ret_type, ir.LiteralStructType):
CReturnTypes = [None] * len(ret_type.elements)
if not CReturnTypes:
MultiRetTypes = [None] * len(ret_type.elements)
if not MultiRetTypes:
# 跨模块多返回值兜底:短名未注册时(函数以 ModulePath.名 /
# sha1.名 全名注册),从其 LiteralStructType 返回类型恢复 CReturnTypes。
# 否则 CReturnTypes 为空会走下方静默 return,目标变量未初始化,
# sha1.名 全名注册),从其 LiteralStructType 返回类型恢复 MultiRetTypes。
# 否则 MultiRetTypes 为空会走下方静默 return,目标变量未初始化,
# 运行期 free(垃圾指针) 触发堆损坏(HashLibTest 0xC0000374)。
func = None
if ModulePath:
@@ -619,10 +623,10 @@ class AssignHandle(BaseHandle):
if func_ft:
ret_type: ir.Type = func_ft.return_type
if isinstance(ret_type, ir.LiteralStructType):
CReturnTypes = [None] * len(ret_type.elements)
if CReturnTypes and len(Target.elts) == len(CReturnTypes):
MultiRetTypes = [None] * len(ret_type.elements)
if MultiRetTypes and len(Target.elts) == len(MultiRetTypes):
# 注:此处原有两行 `if func is None: func = ...`,但 func 只在上面
# 「not CReturnTypes」分支里绑定;当 CReturnTypes 来自返回注解
# 「not MultiRetTypes」分支里绑定;当 MultiRetTypes 来自返回注解
# (`-> tuple[T1, T2]`)时该分支未执行 ⇒ UnboundLocalError 崩溃。
# 且紧接着的 `func = Gen.functions.get(FuncName)` 本就覆盖它,
# 故直接删除(`a, b = f()` 因此从未真正跑通)。
@@ -670,8 +674,8 @@ class AssignHandle(BaseHandle):
VarName: str = elt.id
field_val: ir.Value = Gen.builder.extract_value(call_result, j, name=f"extract_{FuncName}_{j}")
VarType: ir.Type
if CReturnTypes[j] is not None:
ReturnTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(CReturnTypes[j], self.Trans.SymbolTable)
if MultiRetTypes[j] is not None:
ReturnTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(MultiRetTypes[j], self.Trans.SymbolTable)
if ReturnTypeInfo is None:
ReturnTypeInfo = CTypeInfo()
ReturnTypeInfo.BaseType = t.CInt()
@@ -684,7 +688,7 @@ class AssignHandle(BaseHandle):
VarType = ir.IntType(32)
var: ir.AllocaInstr = Gen._alloca(VarType, name=VarName)
Gen.variables[VarName] = var
if CReturnTypes[j] is not None:
if MultiRetTypes[j] is not None:
Gen._record_var_signedness(VarName, str(ReturnTypeInfo) if ReturnTypeInfo else '')
elif ret_type and isinstance(ret_type, ir.LiteralStructType) and j < len(ret_type.elements):
elem_type: ir.Type = ret_type.elements[j]
@@ -697,7 +701,7 @@ class AssignHandle(BaseHandle):
Gen._record_var_signedness(VarName, 'unsigned long long')
Gen._store(field_val, var)
elif isinstance(Node.value, ast.Call):
# fail-fast:多返回值赋值但 CReturnTypes 解析失败(跨模块签名丢失),
# fail-fast:多返回值赋值但 MultiRetTypes 解析失败(跨模块签名丢失),
# 绝不能静默跳过——目标变量不会被初始化,运行期 free(垃圾指针)
# 触发堆损坏(HashLibTest 0xC0000374)。
target_names: list[str] = [
@@ -705,7 +709,7 @@ class AssignHandle(BaseHandle):
]
raise Exception(
f"多返回值赋值解析失败: '{FuncName}' 的返回类型无法解析为"
f"元组/CReturn(ModulePath={ModulePath}),目标 {target_names} 未被初始化"
f"返回注解 `-> tuple[...]`(ModulePath={ModulePath}),目标 {target_names} 未被初始化"
f"{Gen._get_node_info()}"
)
return
+2 -2
View File
@@ -411,7 +411,7 @@ class ForHandle(BaseHandle):
saved_var_signedness: dict[str, str] = Gen.var_signedness.copy()
saved_var_type_info: dict[str, dict[str, str]] = Gen.var_type_info.copy()
saved_var_type_assignments: dict[str, list[dict[str, str]]] = Gen.var_type_assignments.copy()
saved_CurrentCReturnTypes: object | None = getattr(self.Trans, 'CurrentCReturnTypes', None)
saved_CurrentMultiRetTypes: object | None = getattr(self.Trans, 'CurrentMultiRetTypes', None)
saved_CurrentCpythonObjectClass: str | None = getattr(self.Trans, '_CurrentCpythonObjectClass', None)
saved_VarScopes: int = len(self.Trans.VarScopes)
self.Trans.FunctionHandler._EmitFunctionLlvm(Node, Gen, extra_params=extra_params if extra_params else None)
@@ -423,7 +423,7 @@ class ForHandle(BaseHandle):
Gen.var_signedness = saved_var_signedness
Gen.var_type_info = saved_var_type_info
Gen.var_type_assignments = saved_var_type_assignments
self.Trans.CurrentCReturnTypes = saved_CurrentCReturnTypes
self.Trans.CurrentMultiRetTypes = saved_CurrentMultiRetTypes
self.Trans._CurrentCpythonObjectClass = saved_CurrentCpythonObjectClass
while len(self.Trans.VarScopes) > saved_VarScopes:
self.Trans.VarScopes.pop()
+40 -31
View File
@@ -20,6 +20,20 @@ from lib.includes.t import CTypeRegistry
# t 模块存储类标记装饰器名称集合
_T_STORAGE_DECORATORS = frozenset({'CExport', 'CExtern', 'CStatic', 'State', 'CInline', 'TLS'})
# `@c.CReturn` 装饰器已移除;任何地方遇到都必须 fail-fast,不得静默忽略或改写。
_CRETURN_REMOVED_HINT: str = (
"`@c.CReturn` 已移除:请改用返回注解 `-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)"
)
def _RejectCReturnDecorator(node: ast.AST, decorators: list[ast.AST]) -> None:
"""扫到 `@c.CReturn` 装饰器即 fail-fast 报错(该装饰器已移除)。"""
for decorator in decorators:
if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
if decorator.func.attr == 'CReturn':
func_name: str = getattr(node, 'name', '<unknown>')
raise SyntaxError(f"函数 '{func_name}':{_CRETURN_REMOVED_HINT}")
def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool:
"""判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。
@@ -489,13 +503,9 @@ class FunctionHandle(BaseHandle):
def _GetFunctionSignatureLlvm(self, Node: ast.FunctionDef, Gen: LlvmCodeGenerator, ClassName: str | None = None, extra_params: list[tuple[str, Any]] | None = None) -> tuple[str, ir.FunctionType, Any, list[Any], list[ast.AST], bool, str | None, bool]:
FuncName, RawFuncName, func_meta = self._compute_func_name_meta(Node, ClassName)
CReturnTypes: list[ast.AST] = []
if Node.decorator_list:
for decorator in Node.decorator_list:
if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
if decorator.func.attr == 'CReturn':
for arg in decorator.args:
CReturnTypes.append(arg)
_RejectCReturnDecorator(Node, Node.decorator_list)
MultiRetTypes: list[ast.AST] = []
if Node.returns:
llvm_attrs: list[str] = self._ExtractLLVMAttrs(Node.returns)
if llvm_attrs:
@@ -506,13 +516,13 @@ class FunctionHandle(BaseHandle):
slice_node: ast.AST = Node.returns.slice
if isinstance(slice_node, ast.Tuple):
for elt in slice_node.elts:
CReturnTypes.append(elt)
MultiRetTypes.append(elt)
else:
CReturnTypes.append(slice_node)
MultiRetTypes.append(slice_node)
IsPtr: bool = False
ReturnTypeInfo: Any = None
if Node.returns:
if CReturnTypes:
if MultiRetTypes:
ReturnTypeInfo = CTypeInfo()
ReturnTypeInfo.BaseType = t.CVoid()
else:
@@ -672,9 +682,9 @@ class FunctionHandle(BaseHandle):
ParamNames: list[str] = []
ParamTypeStrs: list[Any] = []
auto_addr_modes: list[str | None] = []
CReturnLlvmTypes: list[ir.Type] = []
if CReturnTypes:
for i, ReturnTypeNode in enumerate(CReturnTypes):
MultiRetLlvmTypes: list[ir.Type] = []
if MultiRetTypes:
for i, ReturnTypeNode in enumerate(MultiRetTypes):
ReturnTypeInfo = CTypeInfo.FromNode(ReturnTypeNode, self.Trans.SymbolTable)
# 仅指针层数 <=1 才算裸 str/bytes(i8*)。
# `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。
@@ -686,8 +696,8 @@ class FunctionHandle(BaseHandle):
ReturnTypeInfo = CTypeInfo()
ReturnTypeInfo.BaseType = t.CInt()
RetType: ir.Type = Gen._ctype_to_llvm(ReturnTypeInfo)
CReturnLlvmTypes.append(RetType)
ReturnType = ir.LiteralStructType(CReturnLlvmTypes)
MultiRetLlvmTypes.append(RetType)
ReturnType = ir.LiteralStructType(MultiRetLlvmTypes)
for Arg in Node.args.args:
ParamIsUnsigned: bool = False
if Arg.annotation:
@@ -782,7 +792,7 @@ class FunctionHandle(BaseHandle):
while len(auto_addr_modes) < total_params:
auto_addr_modes.append(None)
Gen._auto_addr_params[FuncName] = auto_addr_modes
return FuncName, FuncType, ReturnTypeInfo, ParamTypeStrs, CReturnTypes, IsMethod, ResolvedClassName, IsVariadic
return FuncName, FuncType, ReturnTypeInfo, ParamTypeStrs, MultiRetTypes, IsMethod, ResolvedClassName, IsVariadic
def _is_generic_function(self, Node: ast.FunctionDef) -> bool:
if hasattr(Node, 'type_params') and Node.type_params:
@@ -1201,11 +1211,11 @@ class FunctionHandle(BaseHandle):
FuncType: ir.FunctionType
ReturnTypeInfo: Any
ParamTypeStrs: list[Any]
CReturnTypes: list[ast.AST]
MultiRetTypes: list[ast.AST]
IsMethod: bool
ResolvedClassName: str | None
IsVariadic: bool
FuncName, FuncType, ReturnTypeInfo, ParamTypeStrs, CReturnTypes, IsMethod, ResolvedClassName, IsVariadic = result
FuncName, FuncType, ReturnTypeInfo, ParamTypeStrs, MultiRetTypes, IsMethod, ResolvedClassName, IsVariadic = result
IsUserMarkedExport: bool = False
if Node.returns:
try:
@@ -1315,7 +1325,7 @@ class FunctionHandle(BaseHandle):
# 保存父级 _CurrentCpythonObjectClass,防止嵌套函数发射污染父方法类上下文
# (例如 HandleImport body 内触发 list[ast.ASTptr] 方法发射,结束后会清空 _CurrentCpythonObjectClass)
saved_cpython_class: str | None = self.Trans._CurrentCpythonObjectClass
CReturnTypes = []
MultiRetTypes = []
IsPtr = False
fn_attrs = {}
# 自定义行为装饰器列表,用于生成 wrapper 函数
@@ -1349,8 +1359,7 @@ class FunctionHandle(BaseHandle):
continue
if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
if decorator.func.attr == 'CReturn':
for arg in decorator.args:
CReturnTypes.append(arg)
_RejectCReturnDecorator(Node, [decorator])
elif decorator.func.attr == 'Attribute' and isinstance(decorator.func.value, ast.Name) and decorator.func.value.id == 'c':
for arg in decorator.args:
if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Attribute):
@@ -1396,9 +1405,9 @@ class FunctionHandle(BaseHandle):
slice_node = Node.returns.slice
if isinstance(slice_node, ast.Tuple):
for elt in slice_node.elts:
CReturnTypes.append(elt)
MultiRetTypes.append(elt)
else:
CReturnTypes.append(slice_node)
MultiRetTypes.append(slice_node)
# 先强制检查 str 类型注解
is_str_return = False
@@ -1423,7 +1432,7 @@ class FunctionHandle(BaseHandle):
ReturnTypeInfo.BaseType = t.CChar()
ReturnTypeInfo.PtrCount = 1
elif Node.returns:
if CReturnTypes:
if MultiRetTypes:
ReturnTypeInfo = CTypeInfo()
ReturnTypeInfo.BaseType = t.CVoid()
else:
@@ -1634,9 +1643,9 @@ class FunctionHandle(BaseHandle):
except Exception as _e:
if _config_mode == "strict":
self.Trans.LogWarning(f"异常被忽略: {_e}")
if CReturnTypes:
CReturnLlvmTypes = []
for i, ReturnTypeNode in enumerate(CReturnTypes):
if MultiRetTypes:
MultiRetLlvmTypes = []
for i, ReturnTypeNode in enumerate(MultiRetTypes):
ReturnTypeInfo = CTypeInfo.FromNode(ReturnTypeNode, self.Trans.SymbolTable)
# 仅指针层数 <=1 才算裸 str/bytes(i8*)。
# `str | t.CPtr` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平。
@@ -1648,11 +1657,11 @@ class FunctionHandle(BaseHandle):
ReturnTypeInfo = CTypeInfo()
ReturnTypeInfo.BaseType = t.CInt()
RetType = Gen._ctype_to_llvm(ReturnTypeInfo)
CReturnLlvmTypes.append(RetType)
ReturnType = ir.LiteralStructType(CReturnLlvmTypes)
self.Trans.CurrentCReturnTypes = CReturnTypes
MultiRetLlvmTypes.append(RetType)
ReturnType = ir.LiteralStructType(MultiRetLlvmTypes)
self.Trans.CurrentMultiRetTypes = MultiRetTypes
else:
self.Trans.CurrentCReturnTypes = None
self.Trans.CurrentMultiRetTypes = None
self._apply_struct_self_cls_types(ParamTypes, ParamNames, IsMethod, IsClassMethod, ResolvedClassName, Gen)
IsVariadic = Node.args.vararg is not None
if extra_params:
@@ -2160,7 +2169,7 @@ class FunctionHandle(BaseHandle):
Gen.global_struct_class = saved_global_struct_class
Gen._variadic_info = None
self.Trans._CurrentCpythonObjectClass = saved_cpython_class
self.Trans.CurrentCReturnTypes = None
self.Trans.CurrentMultiRetTypes = None
if self.Trans.VarScopes:
self.Trans.VarScopes.pop()
self.Trans.FunctionReturnTypes[FuncName] = ReturnTypeInfo
+5 -6
View File
@@ -1421,13 +1421,15 @@ class ImportHandle(BaseHandle):
Gen._export_extern_funcs[FuncName] = _src_sha1
if FuncName in Gen.functions:
return
CReturnTypes = []
if Node.decorator_list:
for decorator in Node.decorator_list:
if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute):
# fail-fast:`@c.CReturn` 已移除,扫到即报错。
if decorator.func.attr == 'CReturn':
for arg in decorator.args:
CReturnTypes.append(arg)
raise SyntaxError(
f"函数 '{FuncName}':`@c.CReturn` 已移除:请改用返回注解 "
f"`-> tuple[ty1, ty2, ...]`(多返回值打包为 struct)"
)
IsPtr = False
ReturnTypeInfo = None
if Node.returns:
@@ -1567,9 +1569,6 @@ class ImportHandle(BaseHandle):
else:
ParamType = ir.IntType(32)
ParamTypes.append(ParamType)
if CReturnTypes:
for _ in CReturnTypes:
ParamTypes.append(ir.PointerType(ir.IntType(8)))
IsVariadic = Node.args.vararg is not None
FuncType = ir.FunctionType(ReturnType, ParamTypes, var_arg=IsVariadic)
_is_export = False
+5 -5
View File
@@ -81,19 +81,19 @@ class ReturnHandle(BaseHandle):
Gen.emit_return(closure_ret)
return
active_finally: tuple[ir.Block, ir.AllocaInstr, ir.AllocaInstr | None] | None = self._find_active_finally(Gen)
if getattr(self.Trans, 'CurrentCReturnTypes', None) and self.Trans.CurrentCReturnTypes and Node.value:
if getattr(self.Trans, 'CurrentMultiRetTypes', None) and self.Trans.CurrentMultiRetTypes and Node.value:
return_values: list[ast.expr] = []
if isinstance(Node.value, ast.Tuple):
return_values = Node.value.elts
else:
return_values = [Node.value]
if len(return_values) == len(self.Trans.CurrentCReturnTypes):
if len(return_values) == len(self.Trans.CurrentMultiRetTypes):
llvm_vals: list[ir.Value] = []
expected_types: list[ir.Type] = []
for i, val in enumerate(return_values):
ReturnTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(self.Trans.CurrentCReturnTypes[i], self.Trans.SymbolTable)
ReturnTypeInfo: CTypeInfo | None = CTypeInfo.FromNode(self.Trans.CurrentMultiRetTypes[i], self.Trans.SymbolTable)
IsRetPtr: bool = ReturnTypeInfo.IsPtr if ReturnTypeInfo else False
if (isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.IsStr) or (isinstance(self.Trans.CurrentCReturnTypes[i], ast.Name) and self.Trans.CurrentCReturnTypes[i].id == 'str'):
if (isinstance(ReturnTypeInfo, CTypeInfo) and ReturnTypeInfo.IsStr) or (isinstance(self.Trans.CurrentMultiRetTypes[i], ast.Name) and self.Trans.CurrentMultiRetTypes[i].id == 'str'):
IsRetPtr = True
ExpectedType: ir.Type = ReturnTypeInfo.ToLLVM(Gen) if ReturnTypeInfo and ReturnTypeInfo.BaseType else Gen._CType2LLVM('int', IsRetPtr)
expected_types.append(ExpectedType)
@@ -161,7 +161,7 @@ class ReturnHandle(BaseHandle):
else:
Gen.emit_return(zero_val)
return
if getattr(self.Trans, 'CurrentCReturnTypes', None) and self.Trans.CurrentCReturnTypes:
if getattr(self.Trans, 'CurrentMultiRetTypes', None) and self.Trans.CurrentMultiRetTypes:
struct_type: ir.Type = Gen.func.ftype.return_type
if isinstance(struct_type, ir.LiteralStructType):
result: ir.Value = ir.Constant(struct_type, ir.Undefined)
+1 -1
View File
@@ -44,7 +44,7 @@ class BaseTranslatorMixin:
def __init__(self) -> None:
self.VarScopes: list[Dict[str, SymbolNode]] = [{}] # 跟踪变量作用域,第一个是全局作用域
self.FunctionReturnTypes: Dict[str, CTypeInfo] = {} # 记录函数名和其返回类型
self.CurrentCReturnTypes: list[CTypeInfo] | None = None # 当前函数的 CReturn 类型列表
self.CurrentMultiRetTypes: list[CTypeInfo] | None = None # 当前函数的多返回值类型列表(`-> tuple[...]`)
self._CurrentCpythonObjectClass: str | None = None # 当前正在处理的 CPython 对象类名
self.FunctionDefCache: dict = {} # 函数定义缓存
self.OriginalLines: list[str] = [] # 原始代码行
+5 -11
View File
@@ -417,17 +417,11 @@ class Set:
class CReturn:
"""多返回值装饰器
用于实现函数多返回值,通过匿名结构体返回实现。
例如:@c.CReturn(t.CInt, t.CInt) 表示函数返回两个 int 值。
等价于 -> tuple[t.CInt, t.CInt] 返回类型注解。
规则:
1. CReturn 中有几个类型就说明要返回几个值
2. 函数返回类型为匿名结构体 { type1, type2, ... }
3. return 语句使用 insert_value 构建结构体
4. 调用处使用 extract_value 提取各字段
"""【已移除】多返回值装饰器(墓碑)。
该类已移除:源码中写 `@c.CReturn(...)` 会被编译器**报错**(fail-fast),
不会静默忽略或改写。多返回值请改用返回注解 `-> tuple[ty1, ty2, ...]`
(返回多个值的函数打包为 struct 返回,调用处用元组解包接收)。
"""
def __init__(self, *ReturnTypes: Any) -> None:
self.ReturnTypes: tuple[Any, ...] = ReturnTypes