将 EnumName/value/IsSigned 加入 FIELD_ROUTES,消除所有冗余 hasattr/getattr

This commit is contained in:
2026-06-18 19:09:50 +08:00
parent f99666420b
commit d7b98cc9c5
33 changed files with 1722 additions and 1200 deletions

View File

@@ -82,7 +82,7 @@ class AnnAssignHandle(BaseHandle):
IsUnion = False
if ClassName and ClassName in self.Trans.SymbolTable:
TypeInfo = self.Trans.SymbolTable[ClassName]
if hasattr(TypeInfo, 'IsUnion') and TypeInfo.IsUnion:
if TypeInfo.IsUnion:
IsUnion = True
if ClassName and ClassName in Gen.structs:
ObjVal = self.Trans.ExprHandler.HandleExprLlvm(Target.value)

View File

@@ -440,8 +440,8 @@ class AssignHandle:
sym_key = f"{ModulePath}.{FuncName}"
sym_info = self.Trans.SymbolTable.get(sym_key)
if sym_info and sym_info.IsFunction:
ret_type_info = getattr(sym_info, 'FuncPtrReturn', None)
param_type_infos = [pt for _, pt in getattr(sym_info, 'FuncPtrParams', [])]
ret_type_info = sym_info.FuncPtrReturn
param_type_infos = [pt for _, pt in (sym_info.FuncPtrParams or [])]
if ret_type_info:
if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
ret_type = ret_type_info.ToLLVM(Gen)
@@ -616,7 +616,7 @@ class AssignHandle:
if ClassName and ClassName in Gen.structs:
PropKey = f'{ClassName}.{AttrName}'
PropInfo = self.Trans.SymbolTable.get(PropKey)
if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_SETTER in PropInfo.MetaList:
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_SETTER in PropInfo.MetaList:
SelfVar = Gen._get_var_ptr('self')
if SelfVar:
SelfPtr = Gen._load(SelfVar, name="self")
@@ -734,7 +734,7 @@ class AssignHandle:
if ClassName and ClassName in Gen.structs:
PropKey = f'{ClassName}.{AttrName}'
PropInfo = self.Trans.SymbolTable.get(PropKey)
if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_SETTER in PropInfo.MetaList:
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_SETTER in PropInfo.MetaList:
ObjVal = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
SetterFunc = Gen._get_function(PropKey + '$set')
if SetterFunc and ObjVal:
@@ -1222,7 +1222,7 @@ class AssignHandle:
elif isinstance(count_node, ast.Name):
if count_node.id in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[count_node.id]
if isinstance(getattr(SymInfo, 'value', None), int):
if isinstance(SymInfo.value, int):
ArrayCount = SymInfo.value
if ArrayCount == 1 and count_node.id in getattr(Gen, '_define_constants', {}):
DefVal = Gen._define_constants[count_node.id]
@@ -1558,94 +1558,10 @@ class AssignHandle:
Gen.variables[VarName] = GlobalVar
def _eval_const_expr(self, node, Gen):
"""计算常量表达式的值"""
import ast
if isinstance(node, ast.Constant):
return node.value
elif isinstance(node, ast.BinOp):
left = self._eval_const_expr(node.left, Gen)
right = self._eval_const_expr(node.right, Gen)
if left is None or right is None:
return None
if isinstance(node.op, ast.Add):
return left + right
elif isinstance(node.op, ast.Sub):
return left - right
elif isinstance(node.op, ast.Mult):
return left * right
elif isinstance(node.op, ast.Div):
return left // right if isinstance(left, int) and isinstance(right, int) else left / right
elif isinstance(node.op, ast.FloorDiv):
return left // right
elif isinstance(node.op, ast.Mod):
return left % right
elif isinstance(node.op, ast.Pow):
return left ** right
elif isinstance(node.op, ast.LShift):
return left << right
elif isinstance(node.op, ast.RShift):
return left >> right
elif isinstance(node.op, ast.BitOr):
return left | right
elif isinstance(node.op, ast.BitXor):
return left ^ right
elif isinstance(node.op, ast.BitAnd):
return left & right
elif isinstance(node, ast.UnaryOp):
operand = self._eval_const_expr(node.operand, Gen)
if operand is None:
return None
if isinstance(node.op, ast.USub):
return -operand
elif isinstance(node.op, ast.UAdd):
return +operand
elif isinstance(node.op, ast.Invert):
return ~operand
elif isinstance(node, ast.Name):
if node.id in getattr(Gen, '_define_constants', {}):
return Gen._define_constants[node.id]
if node.id in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[node.id]
val = getattr(SymInfo, 'value', None)
if isinstance(val, (int, float)):
return val
if getattr(SymInfo, 'IsDefine', None) and isinstance(getattr(SymInfo, 'DefineValue', None), (int, float)):
return SymInfo.DefineValue
elif isinstance(node, ast.Attribute):
module_name = node.value.id if isinstance(node.value, ast.Name) else None
attr_name = node.attr
if module_name and attr_name:
combined_key = f"{module_name}.{attr_name}"
if combined_key in getattr(Gen, '_define_constants', {}):
val = Gen._define_constants[combined_key]
if isinstance(val, (int, float)):
return int(val) if isinstance(val, float) and val == int(val) else val
for key, SymInfo in self.Trans.SymbolTable.items():
if key.endswith(f".{combined_key}") or key == combined_key:
if getattr(SymInfo, 'IsDefine', None) and isinstance(getattr(SymInfo, 'DefineValue', None), (int, float)):
return int(SymInfo.DefineValue) if isinstance(SymInfo.DefineValue, float) and SymInfo.DefineValue == int(SymInfo.DefineValue) else SymInfo.DefineValue
all_dc = getattr(self.Trans, '_all_define_constants', None) or getattr(Gen, '_all_define_constants', {})
if combined_key in all_dc:
val = all_dc[combined_key]
if isinstance(val, (int, float)):
return int(val) if isinstance(val, float) and val == int(val) else val
if attr_name in all_dc:
val = all_dc[attr_name]
if isinstance(val, (int, float)):
return int(val) if isinstance(val, float) and val == int(val) else val
for dc_key, dc_val in all_dc.items():
if dc_key == attr_name or dc_key.endswith(f".{attr_name}"):
if isinstance(dc_val, (int, float)):
return int(dc_val) if isinstance(dc_val, float) and dc_val == int(dc_val) else dc_val
if attr_name in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[attr_name]
if getattr(SymInfo, 'IsDefine', None) and isinstance(getattr(SymInfo, 'DefineValue', None), (int, float)):
return int(SymInfo.DefineValue) if isinstance(SymInfo.DefineValue, float) and SymInfo.DefineValue == int(SymInfo.DefineValue) else SymInfo.DefineValue
if attr_name in getattr(Gen, '_define_constants', {}):
val = Gen._define_constants[attr_name]
if isinstance(val, (int, float)):
return int(val) if isinstance(val, float) and val == int(val) else val
return None
"""计算常量表达式的值(委托到 ConstEvaluator"""
from lib.core.ConstEvaluator import ConstEvaluator, EvalContext
ctx = EvalContext(Gen=Gen, symtab=self.Trans.SymbolTable)
return ConstEvaluator.eval_full(node, ctx)
def _eval_global_count(self, node, Gen):
val = self._eval_const_expr(node, Gen)

View File

@@ -395,74 +395,8 @@ class CTypeInfo:
@staticmethod
def TryEvalConstExpr(node, SymbolTable):
if isinstance(node, ast.Constant) and isinstance(node.value, int):
return node.value
if isinstance(node, ast.BinOp):
left = CTypeInfo.TryEvalConstExpr(node.left, SymbolTable)
right = CTypeInfo.TryEvalConstExpr(node.right, SymbolTable)
if left is None or right is None:
return None
if isinstance(node.op, ast.Add):
return left + right
elif isinstance(node.op, ast.Sub):
return left - right
elif isinstance(node.op, ast.Mult):
return left * right
elif isinstance(node.op, ast.FloorDiv):
return left // right if right != 0 else None
elif isinstance(node.op, ast.Mod):
return left % right if right != 0 else None
elif isinstance(node.op, ast.LShift):
return left << right
elif isinstance(node.op, ast.RShift):
return left >> right
elif isinstance(node.op, ast.BitOr):
return left | right
elif isinstance(node.op, ast.BitAnd):
return left & right
elif isinstance(node.op, ast.BitXor):
return left ^ right
elif isinstance(node.op, ast.Pow):
return left ** right
return None
if isinstance(node, ast.UnaryOp):
operand = CTypeInfo.TryEvalConstExpr(node.operand, SymbolTable)
if operand is None:
return None
if isinstance(node.op, ast.USub):
return -operand
elif isinstance(node.op, ast.UAdd):
return +operand
elif isinstance(node.op, ast.Invert):
return ~operand
return None
if isinstance(node, ast.Name):
if node.id in SymbolTable:
info = SymbolTable[node.id]
if getattr(info, 'IsDefine', None) and isinstance(getattr(info, 'DefineValue', None), int):
return info.DefineValue
if isinstance(node, ast.Attribute):
parts = []
current = node
while isinstance(current, ast.Attribute):
parts.append(current.attr)
current = current.value
if isinstance(current, ast.Name):
parts.append(current.id)
parts.reverse()
attr_name = parts[-1]
possible_keys = [attr_name, '.'.join(parts)]
for key in possible_keys:
if key in SymbolTable:
info = SymbolTable[key]
if getattr(info, 'IsDefine', None) and isinstance(getattr(info, 'DefineValue', None), int):
return info.DefineValue
if len(parts) >= 2:
for mod_key, mod_info in SymbolTable.items():
if getattr(mod_info, 'IsDefine', None) and isinstance(getattr(mod_info, 'DefineValue', None), int):
if mod_key.endswith('.' + attr_name) or mod_key == attr_name:
return mod_info.DefineValue
return None
from lib.core.ConstEvaluator import ConstEvaluator
return ConstEvaluator.eval_with_symtab(node, SymbolTable)
@classmethod
def FromNode(cls, Node: ast.AST, SymbolTable: dict) -> "CTypeInfo":
@@ -1136,10 +1070,6 @@ class CTypeInfo:
NewInfo._ts.original_type = NewInfo._ts.original_type.Copy()
if NewInfo._ts.array_ptr:
NewInfo._ts.array_ptr = NewInfo._ts.array_ptr.Copy()
# 实例上的动态属性也需要拷贝(如 IsSigned 等)
for key, val in self.__dict__.items():
if key not in ('_ts', '_sm'):
object.__setattr__(NewInfo, key, val)
return NewInfo
def get(self, key, default=None):

View File

@@ -40,7 +40,7 @@ class DeleteHandle(BaseHandle):
if ClassName:
PropKey = f'{ClassName}.{AttrName}'
PropInfo = self.Trans.SymbolTable.get(PropKey)
if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList:
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList:
SelfVar = Gen._get_var_ptr('self')
if SelfVar:
SelfPtr = Gen._load(SelfVar, name="self")
@@ -54,7 +54,7 @@ class DeleteHandle(BaseHandle):
if ClassName:
PropKey = f'{ClassName}.{AttrName}'
PropInfo = self.Trans.SymbolTable.get(PropKey)
if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList:
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList:
obj_val = self.Trans.ExprHandler.HandleExprLlvm(target.value)
if obj_val:
DeleterFunc = Gen._get_function(PropKey + '$del')

View File

@@ -329,7 +329,7 @@ class ExprHandle(BaseHandle):
if VarName not in getattr(Gen, '_define_constants', {}):
try:
sym_info = self.translator.SymbolTable.get(VarName)
if sym_info and getattr(sym_info, 'IsDefine', None) and getattr(sym_info, 'DefineValue', None) is not None:
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
val = sym_info.DefineValue
if isinstance(val, int):
# Use VarType hint if available
@@ -400,9 +400,9 @@ class ExprHandle(BaseHandle):
return ir.Constant(ir.IntType(32), 1 if VarName == 'True' else 0)
if VarName in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[VarName]
if getattr(SymInfo, 'IsEnumMember', None) and isinstance(getattr(SymInfo, 'value', None), int):
if SymInfo.IsEnumMember and isinstance(SymInfo.value, int):
return ir.Constant(ir.IntType(32), SymInfo.value)
if getattr(SymInfo, 'IsFunction', False) or getattr(SymInfo, 'IsFuncPtr', False):
if SymInfo.IsFunction or SymInfo.IsFuncPtr:
MangledName = Gen._mangle_func_name(VarName)
if MangledName in Gen.module.globals:
g = Gen.module.globals[MangledName]

View File

@@ -92,7 +92,7 @@ class ExprAttrHandle(BaseHandle):
PossibleKeys.append(key)
for lookup_key in PossibleKeys:
SymInfo = self.Trans.SymbolTable.get(lookup_key)
if SymInfo and getattr(SymInfo, 'IsDefine', None) and getattr(SymInfo, 'DefineValue', None) is not None:
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
return self._make_define_constant(Gen, SymInfo.DefineValue)
# 也检查 _define_constants
define_constants = getattr(Gen, '_define_constants', {})
@@ -202,7 +202,7 @@ class ExprAttrHandle(BaseHandle):
# 检查 property getter
PropKey = f'{ClassName}.{Node.attr}'
PropInfo = self.Trans.SymbolTable.get(PropKey)
if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_GETTER in PropInfo.MetaList:
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_GETTER in PropInfo.MetaList:
SelfVar = Gen._get_var_ptr('self')
if SelfVar:
SelfPtr = Gen._load(SelfVar, name="self")
@@ -234,16 +234,16 @@ class ExprAttrHandle(BaseHandle):
def _handle_attr_enum(self, Node, VarName):
"""处理枚举成员访问 (VarName 是枚举类型名)"""
SymInfo = self.Trans.SymbolTable.get(VarName)
if not SymInfo or not getattr(SymInfo, 'IsEnum', None):
if not SymInfo or not SymInfo.IsEnum:
return None
if Node.attr in self.Trans.SymbolTable:
MemberInfo = self.Trans.SymbolTable[Node.attr]
if getattr(MemberInfo, 'IsEnumMember', None) and getattr(MemberInfo, 'EnumName', None) == VarName:
if isinstance(getattr(MemberInfo, 'value', None), int):
if MemberInfo.IsEnumMember and MemberInfo.EnumName == VarName:
if isinstance(MemberInfo.value, int):
return ir.Constant(ir.IntType(32), MemberInfo.value)
for key, info in self.Trans.SymbolTable.items():
if getattr(info, 'IsEnumMember', None) and getattr(info, 'EnumName', None) == VarName and key == Node.attr:
if isinstance(getattr(info, 'value', None), int):
if info.IsEnumMember and info.EnumName == VarName and key == Node.attr:
if isinstance(info.value, int):
return ir.Constant(ir.IntType(32), info.value)
return None
@@ -285,7 +285,7 @@ class ExprAttrHandle(BaseHandle):
# 检查 property getter
PropKey = f'{ClassName}.{AttrName}'
PropInfo = self.Trans.SymbolTable.get(PropKey)
if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_GETTER in PropInfo.MetaList:
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_GETTER in PropInfo.MetaList:
ObjVal = self.HandleExprLlvm(Node.value)
GetterFunc = Gen._get_function(PropKey)
if GetterFunc and ObjVal:
@@ -297,7 +297,7 @@ class ExprAttrHandle(BaseHandle):
TypeInfo = self.Trans.SymbolTable.get(ClassName)
IsUnion = TypeInfo.IsUnion if TypeInfo else False
IsCenum = TypeInfo.IsEnum if TypeInfo else False
IsRenum = getattr(TypeInfo, 'IsRenum', False) if TypeInfo else False
IsRenum = TypeInfo.IsRenum if TypeInfo else False
# REnum 处理
if IsRenum:
@@ -322,12 +322,12 @@ class ExprAttrHandle(BaseHandle):
for qname in (f"{ClassName}.{AttrName}", f"{ClassName}_{AttrName}"):
if qname in self.Trans.SymbolTable:
info = self.Trans.SymbolTable[qname]
if getattr(info, 'IsEnumMember', None) and isinstance(getattr(info, 'value', None), int):
if info.IsEnumMember and isinstance(info.value, int):
return ir.Constant(ir.IntType(32), info.value)
for key, info in self.Trans.SymbolTable.items():
if key == AttrName:
if getattr(info, 'IsEnumMember', None) and getattr(info, 'EnumName', None) == ClassName:
if isinstance(getattr(info, 'value', None), int):
if info.IsEnumMember and info.EnumName == ClassName:
if isinstance(info.value, int):
return ir.Constant(ir.IntType(32), info.value)
break
@@ -1062,7 +1062,7 @@ class ExprAttrHandle(BaseHandle):
possible_keys.append(key)
for lookup_key in possible_keys:
SymInfo = self.Trans.SymbolTable.get(lookup_key)
if SymInfo and getattr(SymInfo, 'IsDefine', None) and getattr(SymInfo, 'DefineValue', None) is not None:
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
val = SymInfo.DefineValue
if isinstance(val, int):
if val > 0x7FFFFFFF or val < -0x80000000:
@@ -1085,21 +1085,21 @@ class ExprAttrHandle(BaseHandle):
for enum_key in enum_keys:
if enum_key in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[enum_key]
if getattr(SymInfo, 'IsEnum', None):
if SymInfo.IsEnum:
for qname in (f"{enum_key}.{member_name}", f"{enum_key}_{member_name}"):
if qname in self.Trans.SymbolTable:
info = self.Trans.SymbolTable[qname]
if getattr(info, 'IsEnumMember', None) and isinstance(getattr(info, 'value', None), int):
if info.IsEnumMember and isinstance(info.value, int):
return ir.Constant(ir.IntType(32), info.value)
for key, info in self.Trans.SymbolTable.items():
if getattr(info, 'IsEnumMember', None) and getattr(info, 'EnumName', None) == enum_key and key == member_name:
if isinstance(getattr(info, 'value', None), int):
if info.IsEnumMember and info.EnumName == enum_key and key == member_name:
if isinstance(info.value, int):
return ir.Constant(ir.IntType(32), info.value)
for key, info in self.Trans.SymbolTable.items():
if getattr(info, 'IsEnumMember', None) and key == member_name:
if isinstance(getattr(info, 'value', None), int):
if info.IsEnumMember and key == member_name:
if isinstance(info.value, int):
for enum_key in enum_keys:
if getattr(info, 'EnumName', None) == enum_key:
if info.EnumName == enum_key:
return ir.Constant(ir.IntType(32), info.value)
return None

View File

@@ -539,7 +539,7 @@ class ExprBuiltinHandle(BaseHandle):
LastPart = arg.attr
if LastPart in self.Trans.SymbolTable:
AttrInfo = self.Trans.SymbolTable[LastPart]
if getattr(AttrInfo, 'IsEnumMember', None) and getattr(AttrInfo, 'EnumName', None):
if AttrInfo.IsEnumMember and AttrInfo.EnumName:
enum_type_name = AttrInfo.EnumName
elif isinstance(arg.value, ast.Attribute):
attr_path = _get_attr_path(arg)
@@ -554,14 +554,14 @@ class ExprBuiltinHandle(BaseHandle):
for qname in (qualified_name_dot, qualified_name_under):
if qname in self.Trans.SymbolTable:
info = self.Trans.SymbolTable[qname]
if getattr(info, 'IsEnumMember', None) and getattr(info, 'EnumName', None) == enum_class_name:
if info.IsEnumMember and info.EnumName == enum_class_name:
enum_member_found = info
break
if not enum_member_found:
for key in self.Trans.SymbolTable:
if key == LastPart:
info = self.Trans.SymbolTable[key]
if getattr(info, 'IsEnumMember', None) and getattr(info, 'EnumName', None) == enum_class_name:
if info.IsEnumMember and info.EnumName == enum_class_name:
enum_member_found = info
break
if enum_member_found:

View File

@@ -435,7 +435,7 @@ class ExprCallHandle(BaseHandle):
if first_part in aliases:
ModulePath = aliases[first_part] + ModulePath[len(first_part):]
is_instance_var = isinstance(Node.func.value, ast.Name) and Node.func.value.id in Gen.var_struct_class and Node.func.value.id not in Gen.ModuleSha1Map
is_class_name = isinstance(Node.func.value, ast.Name) and (Node.func.value.id in Gen.structs or (Node.func.value.id in self.Trans.SymbolTable and getattr(self.Trans.SymbolTable[Node.func.value.id], 'IsStruct', False)))
is_class_name = isinstance(Node.func.value, ast.Name) and (Node.func.value.id in Gen.structs or (Node.func.value.id in self.Trans.SymbolTable and self.Trans.SymbolTable[Node.func.value.id].IsStruct))
if is_instance_var and not is_class_name:
return self._HandleMethodCallLlvm(Node)
FuncAttr = Node.func.attr
@@ -454,11 +454,11 @@ class ExprCallHandle(BaseHandle):
result = self._HandleClassNewLlvm(Node, FuncAttr)
if result is not None:
return result
if getattr(SymInfo, 'IsEnumMember', False) and getattr(SymInfo, 'EnumName', None):
if SymInfo.IsEnumMember and SymInfo.EnumName:
EnumName = SymInfo.EnumName
if EnumName in self.Trans.SymbolTable:
EnumInfo = self.Trans.SymbolTable[EnumName]
if getattr(EnumInfo, 'IsRenum', False):
if EnumInfo.IsRenum:
result = self._HandleREnumConstructLlvm(Node, EnumName, FuncAttr, SymInfo.value)
if result is not None:
return result
@@ -480,9 +480,9 @@ class ExprCallHandle(BaseHandle):
FullAttrKey = f"{ModulePath}.{FuncAttr}"
if FullAttrKey in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[FullAttrKey]
if getattr(SymInfo, 'IsTypedef', False):
if SymInfo.IsTypedef:
return ir.Constant(ir.IntType(32), 0)
if getattr(SymInfo, 'IsStruct', False):
if SymInfo.IsStruct:
if FuncAttr not in Gen.structs:
self._ensure_struct_declared(FuncAttr)
if FuncAttr in Gen.structs:
@@ -533,7 +533,7 @@ class ExprCallHandle(BaseHandle):
raise Exception(f"Undefined method: 't.{FuncAttr}'")
if isinstance(Node.func.value, ast.Attribute):
inner_attr = Node.func.value.attr
if inner_attr in Gen.structs or (inner_attr in self.Trans.SymbolTable and getattr(self.Trans.SymbolTable[inner_attr], 'IsStruct', False)):
if inner_attr in Gen.structs or (inner_attr in self.Trans.SymbolTable and self.Trans.SymbolTable[inner_attr].IsStruct):
static_result = self._HandleStaticMethodCallLlvm(Node, inner_attr, FuncAttr)
if static_result is not None:
return static_result
@@ -569,11 +569,11 @@ class ExprCallHandle(BaseHandle):
if FuncAttr and ModulePath and ModulePath not in {'t', 'c'}:
# 先检查 FuncAttr 是否是函数/变量,如果是则跳过 struct 声明
_attr_sym = self.Trans.SymbolTable.get(FuncAttr)
_is_func_or_var = _attr_sym and (getattr(_attr_sym, 'IsFunction', False) or getattr(_attr_sym, 'IsVariable', False))
_is_func_or_var = _attr_sym and (_attr_sym.IsFunction or _attr_sym.IsVariable)
if not _is_func_or_var and ModulePath:
_full_key = f"{ModulePath}.{FuncAttr}"
_full_sym = self.Trans.SymbolTable.get(_full_key)
if _full_sym and (getattr(_full_sym, 'IsFunction', False) or getattr(_full_sym, 'IsVariable', False)):
if _full_sym and (_full_sym.IsFunction or _full_sym.IsVariable):
_is_func_or_var = True
# 优先检查 FuncAttr 是否为 struct/类构造器
if not _is_func_or_var and FuncAttr not in Gen.structs:
@@ -587,7 +587,7 @@ class ExprCallHandle(BaseHandle):
FullAttrKey = f"{ModulePath}.{FuncAttr}"
if FullAttrKey in self.Trans.SymbolTable:
FullSymInfo = self.Trans.SymbolTable[FullAttrKey]
if getattr(FullSymInfo, 'IsStruct', False) or getattr(FullSymInfo, 'IsCpythonObject', False):
if FullSymInfo.IsStruct or FullSymInfo.IsCpythonObject:
if FuncAttr not in Gen.structs:
self._ensure_struct_declared(FuncAttr)
if FuncAttr in Gen.structs:
@@ -649,7 +649,7 @@ class ExprCallHandle(BaseHandle):
Gen = self.Trans.LlvmGen
# 如果名称是函数或变量,不应创建 struct
SymInfo = self.Trans.SymbolTable.get(class_name)
if SymInfo and (getattr(SymInfo, 'IsFunction', False) or getattr(SymInfo, 'IsVariable', False)):
if SymInfo and (SymInfo.IsFunction or SymInfo.IsVariable):
return
if class_name in Gen.structs:
existing = Gen.structs[class_name]
@@ -721,16 +721,16 @@ class ExprCallHandle(BaseHandle):
SymKey = f'{ClassName}.{MethodName}'
SymInfo = self.Trans.SymbolTable.get(SymKey) or self.Trans.SymbolTable.get(MethodName)
if SymInfo and SymInfo.IsFunction:
ret_type_info = getattr(SymInfo, 'FuncPtrReturn', None)
ret_type_info = SymInfo.FuncPtrReturn
if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
ret_type = ret_type_info.ToLLVM(Gen)
else:
ret_type = Gen._CType2LLVM('i32', False)
param_type_infos = [pt for _, pt in (getattr(SymInfo, 'FuncPtrParams', None) or [])]
param_type_infos = [pt for _, pt in (SymInfo.FuncPtrParams or [])]
if isinstance(ret_type, ir.VoidType):
ret_type = ir.IntType(32)
llvm_param_types = []
is_static = hasattr(SymInfo, 'MetaList') and FuncMeta.STATIC_METHOD in SymInfo.MetaList
is_static = FuncMeta.STATIC_METHOD in SymInfo.MetaList
if ClassName in Gen.structs and not is_static:
llvm_param_types.append(ir.PointerType(Gen.structs[ClassName]))
for pt in param_type_infos:
@@ -762,8 +762,8 @@ class ExprCallHandle(BaseHandle):
CallArgs = []
SymKey = f'{ClassName}.{MethodName}'
SymInfo = self.Trans.SymbolTable.get(SymKey) or self.Trans.SymbolTable.get(MethodName)
is_static_call = SymInfo is not None and hasattr(SymInfo, 'MetaList') and FuncMeta.STATIC_METHOD in SymInfo.MetaList
is_classmethod_call = SymInfo is not None and hasattr(SymInfo, 'MetaList') and FuncMeta.CLASS_METHOD in SymInfo.MetaList
is_static_call = SymInfo is not None and FuncMeta.STATIC_METHOD in SymInfo.MetaList
is_classmethod_call = SymInfo is not None and FuncMeta.CLASS_METHOD in SymInfo.MetaList
# @classmethod: 在参数列表前插入 cls栈上分配的类实例指针
if is_classmethod_call and ClassName in Gen.structs:
ClsPtr = Gen._alloca(Gen.structs[ClassName], name=f"cls_{ClassName}")
@@ -1230,13 +1230,13 @@ class ExprCallHandle(BaseHandle):
mangled_name = Gen._mangle_func_name(func_name, ModulePath)
sym_key = f'{ModulePath}.{func_name}'
sym_info = self.Trans.SymbolTable.get(sym_key) or self.Trans.SymbolTable.get(func_name)
is_inline = sym_info and (getattr(sym_info, 'IsInline', False) or isinstance(getattr(sym_info, 'Storage', None), t.CInline))
if is_inline and getattr(sym_info, 'InlineBody', None):
is_inline = sym_info and (sym_info.IsInline or isinstance(sym_info.Storage, t.CInline))
if is_inline and sym_info.InlineBody:
self._HandleInlineExpandLlvm(Node, sym_info)
return ir.Constant(ir.IntType(32), 1)
sym_info_exact = self.Trans.SymbolTable.get(sym_key)
if sym_info_exact:
exact_params = getattr(sym_info_exact, 'FuncPtrParams', [])
exact_params = sym_info_exact.FuncPtrParams
exact_param_names = [pn for pn, _ in exact_params]
if exact_param_names:
provided = len(Node.args)
@@ -1280,15 +1280,15 @@ class ExprCallHandle(BaseHandle):
if not sym_info:
sym_info = self.Trans.SymbolTable.get(func_name)
if sym_info:
is_func = getattr(sym_info, 'IsFunction', False)
sym_is_variadic = getattr(sym_info, 'IsVariadic', False)
is_func = sym_info.IsFunction
sym_is_variadic = sym_info.IsVariadic
if is_func:
ret_type_info = getattr(sym_info, 'FuncPtrReturn', None)
ret_type_info = sym_info.FuncPtrReturn
if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
ret_type = ret_type_info.ToLLVM(Gen)
else:
ret_type = Gen._CType2LLVM('i32', False)
sym_params = getattr(sym_info, 'FuncPtrParams', [])
sym_params = sym_info.FuncPtrParams
param_type_infos = [pt for _, pt in sym_params]
if isinstance(ret_type, ir.VoidType):
ret_type = ir.IntType(32)
@@ -1411,15 +1411,15 @@ class ExprCallHandle(BaseHandle):
if not sym_info:
sym_info = self.Trans.SymbolTable.get(func_name)
if sym_info:
is_func = getattr(sym_info, 'IsFunction', False)
sym_is_variadic = getattr(sym_info, 'IsVariadic', False)
is_func = sym_info.IsFunction
sym_is_variadic = sym_info.IsVariadic
if is_func:
ret_type_info = getattr(sym_info, 'FuncPtrReturn', None)
ret_type_info = sym_info.FuncPtrReturn
if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
ret_type = ret_type_info.ToLLVM(Gen)
else:
ret_type = Gen._CType2LLVM('i32', False)
param_type_infos = [pt for _, pt in getattr(sym_info, 'FuncPtrParams', [])]
param_type_infos = [pt for _, pt in sym_info.FuncPtrParams]
if isinstance(ret_type, ir.VoidType):
ret_type = ir.IntType(32)
llvm_param_types = []
@@ -1830,7 +1830,7 @@ class ExprCallHandle(BaseHandle):
if ClassName:
SymKey = f'{ClassName}.{MethodName}'
SymInfo = self.Trans.SymbolTable.get(SymKey)
if SymInfo and hasattr(SymInfo, 'MetaList'):
if SymInfo and SymInfo.MetaList:
if FuncMeta.STATIC_METHOD in SymInfo.MetaList:
return self._HandleStaticMethodCallLlvm(Node, ClassName, MethodName)
if FuncMeta.CLASS_METHOD in SymInfo.MetaList:

View File

@@ -73,7 +73,7 @@ class IfHandle(BaseHandle):
return True
if name in self.Trans.SymbolTable:
info = self.Trans.SymbolTable[name]
if getattr(info, 'IsDefine', False):
if info.IsDefine:
return True
platform_macros = self._get_platform_macros()
return name in platform_macros
@@ -86,8 +86,8 @@ class IfHandle(BaseHandle):
return val
if name in self.Trans.SymbolTable:
info = self.Trans.SymbolTable[name]
if getattr(info, 'IsDefine', False):
val = getattr(info, 'DefineValue', 0)
if info.IsDefine:
val = info.DefineValue
if isinstance(val, (int, float)):
return val
platform_macros = self._get_platform_macros()
@@ -129,118 +129,21 @@ class IfHandle(BaseHandle):
return macros
def _eval_const_expr(self, node):
if isinstance(node, ast.Constant):
val = node.value
if isinstance(val, bool):
return 1 if val else 0
if isinstance(val, int):
return val
if isinstance(val, float):
return 1 if val != 0.0 else 0
return 0
if isinstance(node, ast.Name):
name = node.id
val = self._get_macro_value(name)
if val is not None:
return val
return None
if isinstance(node, ast.Attribute):
full_key = self._get_attr_full_name(node)
if full_key:
val = self._get_macro_value(full_key)
if val is not None:
return val
short_name = full_key.split('.')[-1] if '.' in full_key else full_key
val = self._get_macro_value(short_name)
if val is not None:
return val
return None
if isinstance(node, ast.UnaryOp):
operand = self._eval_const_expr(node.operand)
if operand is None:
return None
if isinstance(node.op, ast.Not):
return 1 if not operand else 0
if isinstance(node.op, ast.USub):
return -operand
if isinstance(node.op, ast.Invert):
return ~operand
return None
if isinstance(node, ast.BinOp):
left = self._eval_const_expr(node.left)
right = self._eval_const_expr(node.right)
if left is None or right is None:
return None
try:
if isinstance(node.op, ast.Add):
return left + right
elif isinstance(node.op, ast.Sub):
return left - right
elif isinstance(node.op, ast.Mult):
return left * right
elif isinstance(node.op, ast.FloorDiv):
return left // right if right != 0 else 0
elif isinstance(node.op, ast.Mod):
return left % right if right != 0 else 0
elif isinstance(node.op, ast.LShift):
return left << right
elif isinstance(node.op, ast.RShift):
return left >> right
elif isinstance(node.op, ast.BitOr):
return left | right
elif isinstance(node.op, ast.BitAnd):
return left & right
elif isinstance(node.op, ast.BitXor):
return left ^ right
except Exception:
return None
return None
if isinstance(node, ast.BoolOp):
if isinstance(node.op, ast.And):
for val in node.values:
result = self._eval_const_expr(val)
if result is None:
return None
if not result:
return 0
return 1
elif isinstance(node.op, ast.Or):
for val in node.values:
result = self._eval_const_expr(val)
if result is None:
return None
if result:
return 1
return 0
if isinstance(node, ast.Compare):
left = self._eval_const_expr(node.left)
if left is None:
return None
for op, comparator in zip(node.ops, node.comparators):
right = self._eval_const_expr(comparator)
if right is None:
return None
if isinstance(op, ast.Eq):
result = left == right
elif isinstance(op, ast.NotEq):
result = left != right
elif isinstance(op, ast.Lt):
result = left < right
elif isinstance(op, ast.LtE):
result = left <= right
elif isinstance(op, ast.Gt):
result = left > right
elif isinstance(op, ast.GtE):
result = left >= right
else:
return None
if not result:
return 0
return 1
if isinstance(node, ast.Call):
if self._is_cif_call(node):
from lib.core.ConstEvaluator import ConstEvaluator, EvalContext
Gen = self.Trans.LlvmGen
ctx = EvalContext(Gen=Gen, symtab=self.Trans.SymbolTable)
result = ConstEvaluator.eval_full(node, ctx)
if result is None:
# 保留 CIf 嵌套调用处理HandlesIf 特有逻辑)
if isinstance(node, ast.Call) and self._is_cif_call(node):
return self._evaluate_cif_condition(node)
return None
return None
# HandlesIf 需要 bool/float → int 转换(#if 条件编译语义)
if isinstance(result, bool):
return 1 if result else 0
if isinstance(result, float):
return 1 if result != 0.0 else 0
return result
def _HandleIfLlvm(self, Node):
Gen = self.Trans.LlvmGen

View File

@@ -74,14 +74,14 @@ class ImportHandle(BaseHandle):
if not asname or asname == name:
# Check if this name is a CDefine constant in SymbolTable
sym_info = self.Trans.SymbolTable.get(name)
if sym_info and getattr(sym_info, 'IsDefine', None) and getattr(sym_info, 'DefineValue', None) is not None:
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
define_constants = vars(Gen).setdefault('_define_constants', {})
if name not in define_constants:
define_constants[name] = sym_info.DefineValue
# Also check with module prefix
for prefix_key in [f"{module}.{name}", name]:
sym_info2 = self.Trans.SymbolTable.get(prefix_key)
if sym_info2 and getattr(sym_info2, 'IsDefine', None) and getattr(sym_info2, 'DefineValue', None) is not None:
if sym_info2 and sym_info2.IsDefine and sym_info2.DefineValue is not None:
define_constants = vars(Gen).setdefault('_define_constants', {})
if name not in define_constants:
define_constants[name] = sym_info2.DefineValue
@@ -893,7 +893,7 @@ class ImportHandle(BaseHandle):
elif isinstance(value_node, ast.Name):
if value_node.id in getattr(self.Trans, 'SymbolTable', {}):
info = self.Trans.SymbolTable[value_node.id]
if getattr(info, 'IsDefine', None) and getattr(info, 'DefineValue', None) is not None:
if info.IsDefine and info.DefineValue is not None:
return info.DefineValue
elif isinstance(value_node, ast.Call):
if isinstance(value_node.func, ast.Attribute):
@@ -1020,7 +1020,7 @@ class ImportHandle(BaseHandle):
ParamTypes = []
is_method = is_class_method or '.__' in FuncName
class_name_for_method = FuncName.split('.')[0] if '.' in FuncName else None
class_is_cpython = class_name_for_method and class_name_for_method in self.Trans.SymbolTable and getattr(self.Trans.SymbolTable[class_name_for_method], 'IsCpythonObject', False)
class_is_cpython = class_name_for_method and class_name_for_method in self.Trans.SymbolTable and self.Trans.SymbolTable[class_name_for_method].IsCpythonObject
for i, Arg in enumerate(Node.args.args):
if i == 0 and is_method:
# self parameter of a method should always be a pointer to the struct

View File

@@ -21,7 +21,7 @@ class MatchHandle(BaseHandle):
VarName = Node.subject.id
if VarName in self.Trans.SymbolTable:
TypeInfo = self.Trans.SymbolTable[VarName]
if getattr(TypeInfo, 'IsRenum', False):
if TypeInfo.IsRenum:
IsRenumMatch = True
RenumName = TypeInfo.Name
SubjectPtr = Gen._loadVar(VarName)
@@ -37,11 +37,11 @@ class MatchHandle(BaseHandle):
VariantName = cls_node.attr
if VariantName and VariantName in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[VariantName]
if getattr(SymInfo, 'IsEnumMember', False) and getattr(SymInfo, 'EnumName', None):
if SymInfo.IsEnumMember and SymInfo.EnumName:
EnumName = SymInfo.EnumName
if EnumName in self.Trans.SymbolTable:
EnumInfo = self.Trans.SymbolTable[EnumName]
if getattr(EnumInfo, 'IsRenum', False):
if EnumInfo.IsRenum:
IsRenumMatch = True
RenumName = EnumName
if SubjectPtr is None:
@@ -209,7 +209,7 @@ class MatchHandle(BaseHandle):
TagValue = None
if VariantName in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[VariantName]
if getattr(SymInfo, 'IsEnumMember', False):
if SymInfo.IsEnumMember:
TagValue = SymInfo.value
if TagValue is not None:
CaseValues.append(ir.Constant(ir.IntType(32), TagValue))

View File

@@ -120,8 +120,8 @@ class HandlesTypeMerge(BaseHandle):
# 也尝试在符号表中查找模块别名
if ModulePath in self.Trans.SymbolTable:
entry = self.Trans.SymbolTable[ModulePath]
if isinstance(entry, CTypeInfo) and getattr(entry, 'IsModuleAlias', False):
resolved = getattr(entry, 'ResolvedModule', None)
if isinstance(entry, CTypeInfo) and entry.IsModuleAlias:
resolved = entry.ResolvedModule
if resolved:
ModulePath = resolved

View File

@@ -25,7 +25,7 @@ class WithHandle(BaseHandle):
if ClassName and ClassName not in Gen.structs:
if ClassName in self.Trans.SymbolTable:
SymInfo = self.Trans.SymbolTable[ClassName]
if getattr(SymInfo, 'IsStruct', False) or getattr(SymInfo, 'IsRenum', False):
if SymInfo.IsStruct or SymInfo.IsRenum:
pass
else:
ClassName = None