修正了一些错误
This commit is contained in:
1 parent
ca7c2120b8
commit
1837339f69
203 files changed
+374300
-2638
No files matched your search
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user