修正了一些错误

This commit is contained in:
TermiNexus committed 2026-07-26 20:32:26 +08:00
1 parent ca7c2120b8
commit 1837339f69
203 files changed
+374300 -2638

No files matched your search

+112 -15
View File
@@ -1562,30 +1562,127 @@ class ExprCallHandle(BaseHandle):
if not Node.args:
return None
type_info = None
MergeException = None
try:
type_info = getattr(self.Trans, 'TypeMergeHandler', None) and self.Trans.TypeMergeHandler.MergeTypes(Node.func)
except Exception as _e:
MergeException = _e
if _config_mode == "strict":
raise
_vlog().warning(f"解析类型失败: {_e}", "Exception")
if not isinstance(type_info, CTypeInfo):
return None
target_type_str = type_info.ToString()
IsPtr = type_info.IsPtr
if IsPtr and target_type_str and '*' not in target_type_str:
target_type_str += ' *'
if not target_type_str:
return None
if type_info.IsPtr and not IsPtr:
IsPtr = True
if '*' not in target_type_str:
if isinstance(type_info, CTypeInfo):
# 主路径:MergeTypes 成功返回 CTypeInfo,沿用原有逻辑生成类型字符串
target_type_str = type_info.ToString()
IsPtr = type_info.IsPtr
if IsPtr and target_type_str and '*' not in target_type_str:
target_type_str += ' *'
if isinstance(type_info.Storage, t.CExport) or isinstance(type_info.Storage, t.CExtern):
pass
if type_info.IsState:
Gen._export_funcs.add('_type_union_cast')
if not target_type_str:
# Fallback:ToString 返回空字符串时,尝试手动从 BinOp 提取类型字符串
_vlog().warning(
f"_HandleTypeUnionCastLlvm: ToString 返回空字符串,启用 fallback 手动解析 "
f"(type_info={type_info!r})"
)
target_type_str = self._ExtractTypeStrFromUnionBinOp(Node.func)
if target_type_str and type_info.IsPtr and not IsPtr:
if '*' not in target_type_str:
target_type_str += ' *'
if isinstance(type_info.Storage, t.CExport) or isinstance(type_info.Storage, t.CExtern):
pass
if type_info.IsState:
Gen._export_funcs.add('_type_union_cast')
else:
# Fallback 路径:MergeTypes 失败(返回 None 或抛异常)时,手动从 BinOp 提取类型信息
# 处理 (BaseType | t.CPtr) 这种模式,手动解析为 "{BaseType} *"
_vlog().warning(
f"_HandleTypeUnionCastLlvm: MergeTypes 未返回 CTypeInfo "
f"(type_info={type_info!r}, exception={MergeException!r}),启用 fallback 手动解析"
)
target_type_str = self._ExtractTypeStrFromUnionBinOp(Node.func)
if not target_type_str:
# Fallback 也无法解析:记录详细诊断信息后返回 None
_vlog().warning(
f"_HandleTypeUnionCastLlvm: fallback 解析失败,无法确定目标类型 "
f"(Node.func={ast.dump(Node.func)})"
)
return None
return self._HandleTypeCastLlvm(Node.args[0], target_type_str)
def _ExtractTypeStrFromUnionBinOp(self, NodeFunc: ast.AST) -> str | None:
"""Fallback:从类型联合 BinOp 手动提取类型字符串。
处理 (BaseType | t.CPtr) 这种模式,手动解析为 "{BaseType} *"。
支持嵌套的 | 操作(如 (t.CInt | t.CPtr) | t.CStatic)。
策略:
- 递归展平所有 | 操作数
- t.CPtr 视为指针修饰符(生成 "{BaseType} *" 格式)
- 其他 CType 子类作为基础类型(取第一个)
- 跳过存储类/限定符修饰符(CExport/CExtern/CStatic/CConst/CVolatile/CInline 等)
"""
if not isinstance(NodeFunc, ast.BinOp) or not isinstance(NodeFunc.op, ast.BitOr):
return None
# 存储类/限定符/修饰符类型名集合:这些类型在类型联合中只起修饰作用,
# 不是基础类型,应跳过(参考 HandlesTypeMerge._GetCTypeInfoInternal 的分类逻辑)
StorageQualifierNames = {
'CArrayPtr', 'CConst', 'CVolatile', 'CInline',
'CStatic', 'CExtern', 'CExport', 'CAuto', 'CRegister',
'CDefine', 'CPass', 'CTypeDefault', 'State',
'BigEndian', 'LittleEndian',
}
# 递归展平所有 | 操作数
Operands = []
def CollectOperands(node: ast.AST) -> None:
if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
CollectOperands(node.left)
CollectOperands(node.right)
else:
Operands.append(node)
CollectOperands(NodeFunc)
HasCPtr = False # 是否包含 t.CPtr(指针修饰符)
BaseTypeName = None # 基础类型名(如 "CInt"、"CChar")
for Operand in Operands:
AttrName = None
if isinstance(Operand, ast.Attribute):
AttrName = Operand.attr
elif isinstance(Operand, ast.Name):
AttrName = Operand.id
else:
continue
# t.CPtr 是指针修饰符,单独处理(增加一层 *)
if AttrName == 'CPtr':
HasCPtr = True
continue
# 跳过存储类/限定符/修饰符类型,它们不是基础类型
if AttrName in StorageQualifierNames:
continue
# 通过 t 模块获取类型类,验证是否为 CType 子类
TypeClass = getattr(t, AttrName, None)
if not (isinstance(TypeClass, type) and issubclass(TypeClass, t.CType)):
# 非 CType 类,跳过
continue
# 记录第一个非 CPtr 基础类型
if BaseTypeName is None:
BaseTypeName = AttrName
if not BaseTypeName:
return None
# 包含 t.CPtr 时,生成 "{BaseType} *" 格式
# _CType2LLVM 已验证能解析 "CInt *" → i32*(ir.PointerType(ir.IntType(32)))
if HasCPtr:
return f"{BaseTypeName} *"
return BaseTypeName
def _HandleTypeCastLlvm(self, expr_node: ast.AST, target_type_str: str) -> ir.Value | None:
Gen = self.Trans.LlvmGen
val = self.HandleExprLlvm(expr_node)