diff --git a/lib/core/LLVMTypeMapper.py b/lib/core/LLVMTypeMapper.py index f5750a6..4243b10 100644 --- a/lib/core/LLVMTypeMapper.py +++ b/lib/core/LLVMTypeMapper.py @@ -141,14 +141,37 @@ class LLVMTypeMapper: return result if result else 'i32' def get_func_param_type_str(self, annotation_node: ast.AST | None) -> str: - """提取函数参数类型的 LLVM 字符串""" + """提取函数参数类型的 LLVM 字符串。 + + 末尾的「不许静默变 i32」守卫:`Subscript` / 联合(`|`)形态的形参注解若解析结果 + 是 `'i32'`,只可能是**解析失败后的兜底** —— 合法的下标注解是容器 / 泛型 / 定长数组 + (解析出指针、数组或结构体指针),合法的联合写法是 `T | t.CPtr` 这类指针叠加,都 + 不会是 i32。该串会被 `_InsertFuncSymbol` 原样存进符号表(`FuncPtrParams`),再由 + `BuildLLVMFuncTypeFromSig` 物化成形参类型 —— 一旦是 i32,调用点就在 `_adjust_args` + 报「实参 %X* 不能隐式转为 i32」,把真因(**注解没解析出来**)掩盖成"调用点类型 + 不匹配"(现场:CallGenMixin.vp:149 调用 `_specialize_generic_class` 的 + `type_args: list[str]*`)。故此处响亮失败,并带上注解原文。 + """ if annotation_node is None: return 'i8*' + result: str if isinstance(annotation_node, ast.BinOp) and isinstance(annotation_node.op, ast.BitOr): # 统一走 CPtr 感知的联合解析 - return self._resolve_bitor(annotation_node) - result: str = self.get_llvm_type_str(annotation_node) - return result if result else 'i8*' + result = self._resolve_bitor(annotation_node) + else: + result = self.get_llvm_type_str(annotation_node) + if not result: + result = 'i8*' + if result == 'i32' and isinstance(annotation_node, (ast.Subscript, ast.BinOp)): + _text: str + try: + _text = ast.unparse(annotation_node) + except Exception: + _text = f'<{type(annotation_node).__name__}>' + raise TypeNameUnresolvedError( + f"形参注解 '{_text}' 解析失败并落到 i32(下标 / 联合形态的合法结果应为" + f"指针、数组或结构体指针,不会是 i32)—— 拒绝静默降级为 i32") + return result def resolve_typedef_value_type(self, node: ast.AST | None) -> str: """解析 typedef 值表达式的 C 类型字符串"""