diff --git a/README.md b/README.md index fe188ac..33942d0 100644 --- a/README.md +++ b/README.md @@ -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) | diff --git a/lib/Projectrans/DeclarationGenerator.py b/lib/Projectrans/DeclarationGenerator.py index 154ee53..44ee0f2 100644 --- a/lib/Projectrans/DeclarationGenerator.py +++ b/lib/Projectrans/DeclarationGenerator.py @@ -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) diff --git a/lib/core/Handles/HandlesAssign.py b/lib/core/Handles/HandlesAssign.py index 411cd8e..79fb68f 100644 --- a/lib/core/Handles/HandlesAssign.py +++ b/lib/core/Handles/HandlesAssign.py @@ -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 diff --git a/lib/core/Handles/HandlesFor.py b/lib/core/Handles/HandlesFor.py index 8dbcb99..1dff047 100644 --- a/lib/core/Handles/HandlesFor.py +++ b/lib/core/Handles/HandlesFor.py @@ -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() diff --git a/lib/core/Handles/HandlesFunctions.py b/lib/core/Handles/HandlesFunctions.py index 3f81a8a..13f5ca2 100644 --- a/lib/core/Handles/HandlesFunctions.py +++ b/lib/core/Handles/HandlesFunctions.py @@ -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', '') + 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 diff --git a/lib/core/Handles/HandlesImports.py b/lib/core/Handles/HandlesImports.py index c728fb4..1b2ff07 100644 --- a/lib/core/Handles/HandlesImports.py +++ b/lib/core/Handles/HandlesImports.py @@ -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 diff --git a/lib/core/Handles/HandlesReturn.py b/lib/core/Handles/HandlesReturn.py index 503650d..1b71668 100644 --- a/lib/core/Handles/HandlesReturn.py +++ b/lib/core/Handles/HandlesReturn.py @@ -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) diff --git a/lib/core/Translator/BaseTranslator.py b/lib/core/Translator/BaseTranslator.py index e08c987..8197c54 100644 --- a/lib/core/Translator/BaseTranslator.py +++ b/lib/core/Translator/BaseTranslator.py @@ -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] = [] # 原始代码行 diff --git a/lib/includes/c.py b/lib/includes/c.py index 43b07d8..5f9b11a 100644 --- a/lib/includes/c.py +++ b/lib/includes/c.py @@ -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