进行了优化,减少了上帝结构体的符号表占用
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -506,8 +506,6 @@ class TransPyC:
|
|||||||
|
|
||||||
# 从源代码直接预扫描 import 语句,注册别名
|
# 从源代码直接预扫描 import 语句,注册别名
|
||||||
# 注意:不能依赖 Tree 中的 import 节点,因为 ParsePythonFile 可能修改了 AST
|
# 注意:不能依赖 Tree 中的 import 节点,因为 ParsePythonFile 可能修改了 AST
|
||||||
if not getattr(self.translator, '_ImportAliases', None):
|
|
||||||
self.translator._ImportAliases = {}
|
|
||||||
if not getattr(self.translator, '_ImportedModules', None):
|
if not getattr(self.translator, '_ImportedModules', None):
|
||||||
self.translator._ImportedModules = set()
|
self.translator._ImportedModules = set()
|
||||||
_prescan_tree = ast.parse(self.code)
|
_prescan_tree = ast.parse(self.code)
|
||||||
@@ -519,14 +517,14 @@ class TransPyC:
|
|||||||
continue
|
continue
|
||||||
self.translator._ImportedModules.add(_name)
|
self.translator._ImportedModules.add(_name)
|
||||||
if _alias.asname:
|
if _alias.asname:
|
||||||
self.translator._ImportAliases[_alias.asname] = _name
|
self.translator.SymbolTable.import_aliases[_alias.asname] = _name
|
||||||
elif isinstance(_node, ast.ImportFrom):
|
elif isinstance(_node, ast.ImportFrom):
|
||||||
_module_name = _node.module
|
_module_name = _node.module
|
||||||
if _module_name and _module_name not in ('c', 't'):
|
if _module_name and _module_name not in ('c', 't'):
|
||||||
self.translator._ImportedModules.add(_module_name)
|
self.translator._ImportedModules.add(_module_name)
|
||||||
for _alias in _node.names:
|
for _alias in _node.names:
|
||||||
if _alias.asname:
|
if _alias.asname:
|
||||||
self.translator._ImportAliases[_alias.asname] = f"{_module_name}.{_alias.name}"
|
self.translator.SymbolTable.import_aliases[_alias.asname] = f"{_module_name}.{_alias.name}"
|
||||||
|
|
||||||
# 解析代码以提取类型信息(用于 EmbeddedAssignments 和 TypedefAssignments)
|
# 解析代码以提取类型信息(用于 EmbeddedAssignments 和 TypedefAssignments)
|
||||||
# 创建临时文件路径用于解析
|
# 创建临时文件路径用于解析
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class AnnAssignHandle(BaseHandle):
|
|||||||
ClassName = CN
|
ClassName = CN
|
||||||
break
|
break
|
||||||
IsUnion = False
|
IsUnion = False
|
||||||
if ClassName and ClassName in self.Trans.SymbolTable:
|
if ClassName and self.Trans.SymbolTable.has(ClassName):
|
||||||
TypeInfo = self.Trans.SymbolTable[ClassName]
|
TypeInfo = self.Trans.SymbolTable[ClassName]
|
||||||
if TypeInfo.IsUnion:
|
if TypeInfo.IsUnion:
|
||||||
IsUnion = True
|
IsUnion = True
|
||||||
@@ -161,7 +161,7 @@ class AnnAssignHandle(BaseHandle):
|
|||||||
info = CTypeInfo()
|
info = CTypeInfo()
|
||||||
info.IsDefine = True
|
info.IsDefine = True
|
||||||
info.DefineValue = Node.value.value
|
info.DefineValue = Node.value.value
|
||||||
self.Trans.SymbolTable[VarName] = info
|
self.Trans.SymbolTable.insert(VarName, info)
|
||||||
Gen._record_var_signedness(VarName, TypeInfo.IsUInt)
|
Gen._record_var_signedness(VarName, TypeInfo.IsUInt)
|
||||||
return
|
return
|
||||||
if TypeInfo.IsStr or (isinstance(Node.annotation, ast.Name) and Node.annotation.id == 'str'):
|
if TypeInfo.IsStr or (isinstance(Node.annotation, ast.Name) and Node.annotation.id == 'str'):
|
||||||
|
|||||||
@@ -139,10 +139,9 @@ class AssignHandle:
|
|||||||
StructType = Gen.structs[ClassName]
|
StructType = Gen.structs[ClassName]
|
||||||
|
|
||||||
IsUnion = False
|
IsUnion = False
|
||||||
if ClassName in self.Trans.SymbolTable:
|
TypeInfo = self.Trans.SymbolTable.lookup(ClassName)
|
||||||
TypeInfo = self.Trans.SymbolTable[ClassName]
|
if TypeInfo and TypeInfo.IsUnion:
|
||||||
if TypeInfo.IsUnion:
|
IsUnion = True
|
||||||
IsUnion = True
|
|
||||||
|
|
||||||
if IsUnion:
|
if IsUnion:
|
||||||
Value = self.HandleExprLlvm(Node.value)
|
Value = self.HandleExprLlvm(Node.value)
|
||||||
@@ -435,10 +434,10 @@ class AssignHandle:
|
|||||||
CReturnTypes = [None] * len(ret_type.elements)
|
CReturnTypes = [None] * len(ret_type.elements)
|
||||||
if not CReturnTypes:
|
if not CReturnTypes:
|
||||||
sym_key = FuncName
|
sym_key = FuncName
|
||||||
if sym_key not in self.Trans.SymbolTable:
|
if not self.Trans.SymbolTable.has(sym_key):
|
||||||
if ModulePath:
|
if ModulePath:
|
||||||
sym_key = f"{ModulePath}.{FuncName}"
|
sym_key = f"{ModulePath}.{FuncName}"
|
||||||
sym_info = self.Trans.SymbolTable.get(sym_key)
|
sym_info = self.Trans.SymbolTable.lookup(sym_key)
|
||||||
if sym_info and sym_info.IsFunction:
|
if sym_info and sym_info.IsFunction:
|
||||||
ret_type_info = sym_info.FuncPtrReturn
|
ret_type_info = sym_info.FuncPtrReturn
|
||||||
param_type_infos = [pt for _, pt in (sym_info.FuncPtrParams or [])]
|
param_type_infos = [pt for _, pt in (sym_info.FuncPtrParams or [])]
|
||||||
@@ -615,7 +614,7 @@ class AssignHandle:
|
|||||||
ClassName = self.Trans._CurrentCpythonObjectClass
|
ClassName = self.Trans._CurrentCpythonObjectClass
|
||||||
if ClassName and ClassName in Gen.structs:
|
if ClassName and ClassName in Gen.structs:
|
||||||
PropKey = f'{ClassName}.{AttrName}'
|
PropKey = f'{ClassName}.{AttrName}'
|
||||||
PropInfo = self.Trans.SymbolTable.get(PropKey)
|
PropInfo = self.Trans.SymbolTable.lookup(PropKey)
|
||||||
if PropInfo and 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')
|
SelfVar = Gen._get_var_ptr('self')
|
||||||
if SelfVar:
|
if SelfVar:
|
||||||
@@ -726,14 +725,13 @@ class AssignHandle:
|
|||||||
ClassName = CN
|
ClassName = CN
|
||||||
|
|
||||||
IsUnion = False
|
IsUnion = False
|
||||||
if ClassName and ClassName in self.Trans.SymbolTable:
|
TypeInfo = self.Trans.SymbolTable.lookup(ClassName)
|
||||||
TypeInfo = self.Trans.SymbolTable[ClassName]
|
if TypeInfo and TypeInfo.IsUnion:
|
||||||
if TypeInfo.IsUnion:
|
IsUnion = True
|
||||||
IsUnion = True
|
|
||||||
|
|
||||||
if ClassName and ClassName in Gen.structs:
|
if ClassName and ClassName in Gen.structs:
|
||||||
PropKey = f'{ClassName}.{AttrName}'
|
PropKey = f'{ClassName}.{AttrName}'
|
||||||
PropInfo = self.Trans.SymbolTable.get(PropKey)
|
PropInfo = self.Trans.SymbolTable.lookup(PropKey)
|
||||||
if PropInfo and 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)
|
ObjVal = self.Trans.ExprHandler.HandleExprLlvm(Target.value)
|
||||||
SetterFunc = Gen._get_function(PropKey + '$set')
|
SetterFunc = Gen._get_function(PropKey + '$set')
|
||||||
@@ -856,8 +854,7 @@ class AssignHandle:
|
|||||||
self._StoreWithCoerce(Value, MemberPtr)
|
self._StoreWithCoerce(Value, MemberPtr)
|
||||||
if not ClassName:
|
if not ClassName:
|
||||||
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
resolved_mod = self.Trans.SymbolTable.resolve_alias(VarName)
|
||||||
resolved_mod = import_aliases.get(VarName, VarName)
|
|
||||||
if imported_modules and (VarName in imported_modules or resolved_mod in imported_modules):
|
if imported_modules and (VarName in imported_modules or resolved_mod in imported_modules):
|
||||||
PossibleKeys = [f"{VarName}.{AttrName}", AttrName]
|
PossibleKeys = [f"{VarName}.{AttrName}", AttrName]
|
||||||
for mod_name in imported_modules:
|
for mod_name in imported_modules:
|
||||||
@@ -1185,7 +1182,7 @@ class AssignHandle:
|
|||||||
if isinstance(Node.target, ast.Name):
|
if isinstance(Node.target, ast.Name):
|
||||||
VarName = Node.target.id
|
VarName = Node.target.id
|
||||||
EffectiveAnnotation = Node.annotation
|
EffectiveAnnotation = Node.annotation
|
||||||
if VarName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(VarName):
|
||||||
Info = self.Trans.SymbolTable[VarName]
|
Info = self.Trans.SymbolTable[VarName]
|
||||||
if Info.get('type') == 'typedef':
|
if Info.get('type') == 'typedef':
|
||||||
return
|
return
|
||||||
@@ -1200,7 +1197,7 @@ class AssignHandle:
|
|||||||
elem_type_node = slice_node.elts[0]
|
elem_type_node = slice_node.elts[0]
|
||||||
count_node = slice_node.elts[1]
|
count_node = slice_node.elts[1]
|
||||||
if isinstance(elem_type_node, ast.Name) and elem_type_node.id in Gen.structs:
|
if isinstance(elem_type_node, ast.Name) and elem_type_node.id in Gen.structs:
|
||||||
SymEntry = self.Trans.SymbolTable.get(elem_type_node.id)
|
SymEntry = self.Trans.SymbolTable.lookup(elem_type_node.id)
|
||||||
if SymEntry and isinstance(SymEntry, CTypeInfo) and SymEntry.IsFuncPtr:
|
if SymEntry and isinstance(SymEntry, CTypeInfo) and SymEntry.IsFuncPtr:
|
||||||
ElemType = ir.IntType(8).as_pointer()
|
ElemType = ir.IntType(8).as_pointer()
|
||||||
else:
|
else:
|
||||||
@@ -1220,7 +1217,7 @@ class AssignHandle:
|
|||||||
if isinstance(count_node, ast.Constant) and isinstance(count_node.value, int):
|
if isinstance(count_node, ast.Constant) and isinstance(count_node.value, int):
|
||||||
ArrayCount = count_node.value
|
ArrayCount = count_node.value
|
||||||
elif isinstance(count_node, ast.Name):
|
elif isinstance(count_node, ast.Name):
|
||||||
if count_node.id in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(count_node.id):
|
||||||
SymInfo = self.Trans.SymbolTable[count_node.id]
|
SymInfo = self.Trans.SymbolTable[count_node.id]
|
||||||
if isinstance(SymInfo.value, int):
|
if isinstance(SymInfo.value, int):
|
||||||
ArrayCount = SymInfo.value
|
ArrayCount = SymInfo.value
|
||||||
@@ -1324,7 +1321,7 @@ class AssignHandle:
|
|||||||
if TTypeInfo:
|
if TTypeInfo:
|
||||||
TTypeInfo.IsTypedef = True
|
TTypeInfo.IsTypedef = True
|
||||||
TTypeInfo.Name = VarName
|
TTypeInfo.Name = VarName
|
||||||
self.Trans.SymbolTable[VarName] = TTypeInfo
|
self.Trans.SymbolTable.insert(VarName, TTypeInfo)
|
||||||
if IsCDefine:
|
if IsCDefine:
|
||||||
if Node.value:
|
if Node.value:
|
||||||
define_constants = vars(Gen).setdefault('_define_constants', {})
|
define_constants = vars(Gen).setdefault('_define_constants', {})
|
||||||
@@ -1494,12 +1491,12 @@ class AssignHandle:
|
|||||||
enum_class_name = parts[-2]
|
enum_class_name = parts[-2]
|
||||||
member_name = parts[-1]
|
member_name = parts[-1]
|
||||||
qualified_name = f"{enum_class_name}.{member_name}"
|
qualified_name = f"{enum_class_name}.{member_name}"
|
||||||
if qualified_name in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(qualified_name):
|
||||||
info = self.Trans.SymbolTable[qualified_name]
|
info = self.Trans.SymbolTable[qualified_name]
|
||||||
if info.IsEnumMember and info.EnumName:
|
if info.IsEnumMember and info.EnumName:
|
||||||
return info.EnumName
|
return info.EnumName
|
||||||
under_name = f"{enum_class_name}_{member_name}"
|
under_name = f"{enum_class_name}_{member_name}"
|
||||||
if under_name in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(under_name):
|
||||||
info = self.Trans.SymbolTable[under_name]
|
info = self.Trans.SymbolTable[under_name]
|
||||||
if info.IsEnumMember and info.EnumName:
|
if info.IsEnumMember and info.EnumName:
|
||||||
return info.EnumName
|
return info.EnumName
|
||||||
@@ -1529,7 +1526,7 @@ class AssignHandle:
|
|||||||
FuncName = Node.value.func.id
|
FuncName = Node.value.func.id
|
||||||
if FuncName in Gen.structs:
|
if FuncName in Gen.structs:
|
||||||
IsUnion = False
|
IsUnion = False
|
||||||
if FuncName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FuncName):
|
||||||
TypeInfo = self.Trans.SymbolTable[FuncName]
|
TypeInfo = self.Trans.SymbolTable[FuncName]
|
||||||
if TypeInfo.IsUnion:
|
if TypeInfo.IsUnion:
|
||||||
IsUnion = True
|
IsUnion = True
|
||||||
|
|||||||
@@ -359,44 +359,16 @@ class CTypeInfo:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def FromTypeName(TypeName: str) -> "CTypeInfo":
|
def FromTypeName(TypeName: str) -> "CTypeInfo":
|
||||||
"""从简单类型名构造 CTypeInfo(不经过 FromStr 字符串解析)"""
|
"""从简单类型名构造 CTypeInfo(不经过 FromStr 字符串解析)"""
|
||||||
from lib.core.Handles.HandlesBase import BuiltinTypeMap
|
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver
|
||||||
|
return TypeAnnotationResolver.from_type_name(TypeName)
|
||||||
# Handle pointer types like 'CUInt32T *', 'void *', etc.
|
|
||||||
ptr_count = 0
|
|
||||||
base_name = TypeName
|
|
||||||
while base_name.endswith(' *') or base_name.endswith('*'):
|
|
||||||
ptr_count += 1
|
|
||||||
base_name = base_name.rstrip(' *').rstrip()
|
|
||||||
|
|
||||||
entry = BuiltinTypeMap.Get(base_name)
|
|
||||||
if entry:
|
|
||||||
TypeClass, base_ptr = entry
|
|
||||||
info = CTypeInfo()
|
|
||||||
info.BaseType = TypeClass
|
|
||||||
info.PtrCount = base_ptr + ptr_count
|
|
||||||
return info
|
|
||||||
# Handle LLVM primitive type names (e.g., 'i64', 'double' from generic type inference)
|
|
||||||
llvm_map = CTypeInfo._get_llvm_primitive_map()
|
|
||||||
llvm_entry = llvm_map.get(base_name)
|
|
||||||
if llvm_entry:
|
|
||||||
TypeClass, base_ptr = llvm_entry
|
|
||||||
info = CTypeInfo()
|
|
||||||
info.BaseType = TypeClass
|
|
||||||
info.PtrCount = base_ptr + ptr_count
|
|
||||||
return info
|
|
||||||
# Fallback with pointer count
|
|
||||||
info = CTypeInfo.CreateFromTypeName(TypeName)
|
|
||||||
if ptr_count > 0:
|
|
||||||
info.PtrCount = ptr_count
|
|
||||||
return info
|
|
||||||
|
|
||||||
# FromStr 已移除 - 类型解析不再经过中间字符串格式
|
# FromStr 已移除 - 类型解析不再经过中间字符串格式
|
||||||
# typedef 展开直接走 CTypeInfo 对象,不经过字符串解析
|
# typedef 展开直接走 CTypeInfo 对象,不经过字符串解析
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def TryEvalConstExpr(node, SymbolTable):
|
def TryEvalConstExpr(node, SymbolTable):
|
||||||
from lib.core.ConstEvaluator import ConstEvaluator
|
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver
|
||||||
return ConstEvaluator.eval_with_symtab(node, SymbolTable)
|
return TypeAnnotationResolver.try_eval_const_expr(node, SymbolTable)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def FromNode(cls, Node: ast.AST, SymbolTable: dict) -> "CTypeInfo":
|
def FromNode(cls, Node: ast.AST, SymbolTable: dict) -> "CTypeInfo":
|
||||||
@@ -406,658 +378,9 @@ class CTypeInfo:
|
|||||||
Node: AST 节点(如 ast.Name, ast.Attribute 等)
|
Node: AST 节点(如 ast.Name, ast.Attribute 等)
|
||||||
SymbolTable: 符号表字典
|
SymbolTable: 符号表字典
|
||||||
"""
|
"""
|
||||||
if isinstance(Node, (ast.Constant, ast.Str)):
|
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver
|
||||||
return cls._FromNode_Constant(Node, SymbolTable)
|
return TypeAnnotationResolver.from_node(Node, SymbolTable)
|
||||||
if isinstance(Node, ast.Name):
|
|
||||||
return cls._FromNode_Name(Node, SymbolTable)
|
|
||||||
if isinstance(Node, ast.Call):
|
|
||||||
return cls._FromNode_Call(Node, SymbolTable)
|
|
||||||
if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr):
|
|
||||||
return cls._FromNode_BinOp(Node, SymbolTable)
|
|
||||||
if isinstance(Node, ast.Subscript):
|
|
||||||
return cls._FromNode_Subscript(Node, SymbolTable)
|
|
||||||
if isinstance(Node, ast.Attribute):
|
|
||||||
return cls._FromNode_Attribute(Node, SymbolTable)
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _FromNode_Constant(cls, Node: ast.AST, SymbolTable: dict) -> "CTypeInfo":
|
|
||||||
"""处理 ast.Constant / ast.Str 节点"""
|
|
||||||
if isinstance(Node, ast.Constant):
|
|
||||||
TypeName = Node.value
|
|
||||||
else:
|
|
||||||
TypeName = Node.s
|
|
||||||
return cls.FromTypeName(TypeName)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _FromNode_Name(cls, Node: ast.Name, SymbolTable: dict) -> "CTypeInfo":
|
|
||||||
"""处理 ast.Name 节点"""
|
|
||||||
from lib.includes import t
|
|
||||||
|
|
||||||
TypeName = Node.id
|
|
||||||
TypeObj = CTypeHelper.GetTModuleCType(TypeName)
|
|
||||||
if TypeObj is None:
|
|
||||||
TypeObj = getattr(t, TypeName, None)
|
|
||||||
if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType) and TypeObj is not t.CType:
|
|
||||||
if TypeObj == t.CPtr:
|
|
||||||
Result = cls()
|
|
||||||
Result.PtrCount = 1
|
|
||||||
Result.BaseType = t.CVoid()
|
|
||||||
return Result
|
|
||||||
if TypeObj == t.State:
|
|
||||||
Result = cls()
|
|
||||||
Result.IsState = True
|
|
||||||
Result.BaseType = t.CVoid()
|
|
||||||
return Result
|
|
||||||
Inst = TypeObj()
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = TypeObj
|
|
||||||
if hasattr(Inst, 'CName') and Inst.CName:
|
|
||||||
Result.Name = Inst.CName
|
|
||||||
if hasattr(Inst, 'IsSigned'):
|
|
||||||
Result.IsSigned = Inst.IsSigned
|
|
||||||
return Result
|
|
||||||
if TypeName in SymbolTable:
|
|
||||||
Entry = SymbolTable[TypeName]
|
|
||||||
if Entry:
|
|
||||||
if isinstance(Entry, CTypeInfo):
|
|
||||||
if Entry.IsTypedef:
|
|
||||||
if Entry.BaseType and (not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0):
|
|
||||||
Result = Entry.Copy()
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
if Entry.OriginalType:
|
|
||||||
if isinstance(Entry.OriginalType, CTypeInfo) and Entry.OriginalType.IsFuncPtr:
|
|
||||||
Result = cls()
|
|
||||||
Result.IsFuncPtr = True
|
|
||||||
Result.FuncPtrReturn = Entry.OriginalType.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
|
|
||||||
Result.FuncPtrParams = list(Entry.OriginalType.FuncPtrParams) if Entry.OriginalType.FuncPtrParams else []
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
elif isinstance(Entry.OriginalType, CTypeInfo):
|
|
||||||
Resolved = Entry.OriginalType.Copy()
|
|
||||||
elif isinstance(Entry.OriginalType, str) and Entry.OriginalType == 'Callable':
|
|
||||||
Result = cls()
|
|
||||||
Result.IsFuncPtr = True
|
|
||||||
Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
|
|
||||||
Result.FuncPtrParams = []
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
elif isinstance(Entry.OriginalType, str):
|
|
||||||
Resolved = cls.FromTypeName(Entry.OriginalType)
|
|
||||||
else:
|
|
||||||
Resolved = Entry.OriginalType
|
|
||||||
Resolved.IsTypedef = True
|
|
||||||
Resolved.Name = TypeName
|
|
||||||
return Resolved
|
|
||||||
TypeEntry = BuiltinTypeMap.Get(TypeName)
|
|
||||||
if TypeEntry:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = TypeEntry[0]()
|
|
||||||
Result.PtrCount = TypeEntry[1]
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
return Entry
|
|
||||||
if Entry.IsEnum:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.IsEnum = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
if getattr(Entry, 'IsExceptionClass', None):
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.IsExceptionClass = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
if Entry.BaseType is None and (Entry.IsStruct or Entry.Name):
|
|
||||||
Entry.BaseType = t.CStruct(name=TypeName)
|
|
||||||
Entry.IsStruct = True
|
|
||||||
return Entry
|
|
||||||
elif isinstance(Entry, dict):
|
|
||||||
if Entry.get('type') == 'typedef':
|
|
||||||
OriginalType = Entry.get('OriginalType', '')
|
|
||||||
if OriginalType:
|
|
||||||
if OriginalType == 'Callable':
|
|
||||||
Result = cls()
|
|
||||||
Result.IsFuncPtr = True
|
|
||||||
Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
|
|
||||||
Result.FuncPtrParams = []
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
Resolved = cls.FromTypeName(OriginalType)
|
|
||||||
Resolved.IsTypedef = True
|
|
||||||
Resolved.Name = TypeName
|
|
||||||
return Resolved
|
|
||||||
TypeEntry = BuiltinTypeMap.Get(TypeName)
|
|
||||||
if TypeEntry:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = TypeEntry[0]()
|
|
||||||
Result.PtrCount = TypeEntry[1]
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t._CTypedef(TypeName)
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
# 特殊处理 str 类型,它应该是 char*(指针)
|
|
||||||
if TypeName in ('str', 'bytes'):
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CChar()
|
|
||||||
Result.PtrCount = 1
|
|
||||||
return Result
|
|
||||||
if TypeName == 'irq_handler_t':
|
|
||||||
pass
|
|
||||||
return cls.FromTypeName(TypeName)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _FromNode_Call(cls, Node: ast.Call, SymbolTable: dict) -> "CTypeInfo":
|
|
||||||
"""处理 ast.Call 节点"""
|
|
||||||
from lib.includes import t
|
|
||||||
|
|
||||||
if isinstance(Node.func, ast.Name) and Node.func.id == 'callable':
|
|
||||||
Result = cls()
|
|
||||||
Result.IsFuncPtr = True
|
|
||||||
Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
|
|
||||||
Result.FuncPtrParams = []
|
|
||||||
try:
|
|
||||||
if len(Node.args) > 0:
|
|
||||||
RetInfo = cls.FromNode(Node.args[0], SymbolTable)
|
|
||||||
if RetInfo:
|
|
||||||
Result.FuncPtrReturn = RetInfo
|
|
||||||
for kw in Node.keywords:
|
|
||||||
ParamInfo = cls.FromNode(kw.value, SymbolTable)
|
|
||||||
if ParamInfo:
|
|
||||||
Result.FuncPtrParams.append((kw.arg or '', ParamInfo))
|
|
||||||
except Exception as _e:
|
|
||||||
if __import__('lib.constants.config', fromlist=['mode']).mode == "strict":
|
|
||||||
import warnings; warnings.warn(f"异常被忽略: {_e}")
|
|
||||||
return Result
|
|
||||||
if isinstance(Node.func, ast.Attribute):
|
|
||||||
if isinstance(Node.func.value, ast.Name) and Node.func.value.id == 't':
|
|
||||||
if Node.func.attr == 'Bit' and len(Node.args) > 0:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.IsBitField = True
|
|
||||||
if isinstance(Node.args[0], ast.Constant) and isinstance(Node.args[0].value, int):
|
|
||||||
Result.BitWidth = Node.args[0].value
|
|
||||||
else:
|
|
||||||
Result.BitWidth = 1
|
|
||||||
return Result
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _FromNode_BinOp(cls, Node: ast.BinOp, SymbolTable: dict) -> "CTypeInfo":
|
|
||||||
"""处理 ast.BinOp (BitOr) 节点"""
|
|
||||||
from lib.includes import t
|
|
||||||
|
|
||||||
LeftInfo = cls.FromNode(Node.left, SymbolTable)
|
|
||||||
RightInfo = cls.FromNode(Node.right, SymbolTable)
|
|
||||||
|
|
||||||
if LeftInfo.IsState or RightInfo.IsState:
|
|
||||||
Result = cls()
|
|
||||||
Result.IsState = True
|
|
||||||
NonStateInfo = LeftInfo if not LeftInfo.IsState else RightInfo
|
|
||||||
StateInfo = LeftInfo if LeftInfo.IsState else RightInfo
|
|
||||||
if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0):
|
|
||||||
Result.BaseType = NonStateInfo.BaseType
|
|
||||||
elif NonStateInfo.IsTypedef and NonStateInfo.Name:
|
|
||||||
if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0):
|
|
||||||
Result.BaseType = NonStateInfo.BaseType
|
|
||||||
Result.PtrCount = NonStateInfo.PtrCount
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = NonStateInfo.Name
|
|
||||||
if NonStateInfo.OriginalType:
|
|
||||||
Result.OriginalType = NonStateInfo.OriginalType
|
|
||||||
else:
|
|
||||||
Result.BaseType = t.CStruct(name=NonStateInfo.Name)
|
|
||||||
Result.IsStruct = True
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = NonStateInfo.Name
|
|
||||||
if NonStateInfo.OriginalType:
|
|
||||||
Result.OriginalType = NonStateInfo.OriginalType
|
|
||||||
else:
|
|
||||||
Result.BaseType = t.CVoid()
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
if not Result.Storage:
|
|
||||||
Result.Storage = t.CExport()
|
|
||||||
if LeftInfo.Storage and not isinstance(LeftInfo.Storage, t.CExport):
|
|
||||||
Result.Storage = LeftInfo.Storage
|
|
||||||
elif RightInfo.Storage and not isinstance(RightInfo.Storage, t.CExport):
|
|
||||||
Result.Storage = RightInfo.Storage
|
|
||||||
if LeftInfo.DataConst or RightInfo.DataConst:
|
|
||||||
Result.DataConst = True
|
|
||||||
if LeftInfo.VarConst or RightInfo.VarConst:
|
|
||||||
Result.VarConst = True
|
|
||||||
return Result
|
|
||||||
|
|
||||||
if LeftInfo.IsPtr or RightInfo.IsPtr:
|
|
||||||
Result = cls()
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
NonPtrInfo = LeftInfo if not LeftInfo.IsPtr else RightInfo
|
|
||||||
PtrInfo = RightInfo if RightInfo.IsPtr else LeftInfo
|
|
||||||
if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0):
|
|
||||||
Result.BaseType = NonPtrInfo.BaseType
|
|
||||||
elif NonPtrInfo.IsTypedef and NonPtrInfo.Name:
|
|
||||||
if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0):
|
|
||||||
Result.BaseType = NonPtrInfo.BaseType
|
|
||||||
Result.IsTypedef = True
|
|
||||||
Result.Name = NonPtrInfo.Name
|
|
||||||
if NonPtrInfo.OriginalType:
|
|
||||||
Result.OriginalType = NonPtrInfo.OriginalType
|
|
||||||
else:
|
|
||||||
Result.BaseType = t.CStruct(name=NonPtrInfo.Name)
|
|
||||||
Result.IsStruct = True
|
|
||||||
elif PtrInfo.BaseType and (not isinstance(PtrInfo.BaseType, (t._CTypedef,)) or PtrInfo.PtrCount > 0):
|
|
||||||
Result.BaseType = PtrInfo.BaseType
|
|
||||||
else:
|
|
||||||
Result.BaseType = t.CUnsignedChar()
|
|
||||||
if LeftInfo.DataConst or RightInfo.DataConst:
|
|
||||||
Result.DataConst = True
|
|
||||||
if LeftInfo.VarConst or RightInfo.VarConst:
|
|
||||||
Result.VarConst = True
|
|
||||||
if LeftInfo.DataVolatile or RightInfo.DataVolatile:
|
|
||||||
Result.DataVolatile = True
|
|
||||||
if LeftInfo.VarVolatile or RightInfo.VarVolatile:
|
|
||||||
Result.VarVolatile = True
|
|
||||||
if LeftInfo.Storage:
|
|
||||||
Result.Storage = LeftInfo.Storage
|
|
||||||
elif RightInfo.Storage:
|
|
||||||
Result.Storage = RightInfo.Storage
|
|
||||||
return Result
|
|
||||||
|
|
||||||
if LeftInfo.DataConst or RightInfo.DataConst:
|
|
||||||
Result = cls()
|
|
||||||
BaseTypeSide = LeftInfo if not LeftInfo.DataConst else RightInfo
|
|
||||||
QualSide = LeftInfo if LeftInfo.DataConst else RightInfo
|
|
||||||
Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType
|
|
||||||
if not Result.BaseType:
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.DataConst = True
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
if LeftInfo.VarConst or RightInfo.VarConst:
|
|
||||||
Result.VarConst = True
|
|
||||||
if LeftInfo.DataVolatile or RightInfo.DataVolatile:
|
|
||||||
Result.DataVolatile = True
|
|
||||||
if LeftInfo.Storage:
|
|
||||||
Result.Storage = LeftInfo.Storage
|
|
||||||
elif RightInfo.Storage:
|
|
||||||
Result.Storage = RightInfo.Storage
|
|
||||||
return Result
|
|
||||||
|
|
||||||
if LeftInfo.DataVolatile or RightInfo.DataVolatile:
|
|
||||||
Result = cls()
|
|
||||||
BaseTypeSide = LeftInfo if not LeftInfo.DataVolatile else RightInfo
|
|
||||||
QualSide = LeftInfo if LeftInfo.DataVolatile else RightInfo
|
|
||||||
Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType
|
|
||||||
if not Result.BaseType:
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.DataVolatile = True
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
if LeftInfo.VarConst or RightInfo.VarConst:
|
|
||||||
Result.VarConst = True
|
|
||||||
if LeftInfo.Storage:
|
|
||||||
Result.Storage = LeftInfo.Storage
|
|
||||||
elif RightInfo.Storage:
|
|
||||||
Result.Storage = RightInfo.Storage
|
|
||||||
return Result
|
|
||||||
|
|
||||||
if LeftInfo.Storage or RightInfo.Storage:
|
|
||||||
Result = cls()
|
|
||||||
BaseTypeSide = LeftInfo if not LeftInfo.Storage else RightInfo
|
|
||||||
StorageSide = LeftInfo if LeftInfo.Storage else RightInfo
|
|
||||||
if BaseTypeSide.IsState or StorageSide.IsState:
|
|
||||||
Result.IsState = True
|
|
||||||
Result.BaseType = t.CVoid()
|
|
||||||
Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage
|
|
||||||
return Result
|
|
||||||
Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else StorageSide.BaseType
|
|
||||||
if not Result.BaseType:
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
if LeftInfo.DataConst or RightInfo.DataConst:
|
|
||||||
Result.DataConst = True
|
|
||||||
if LeftInfo.VarConst or RightInfo.VarConst:
|
|
||||||
Result.VarConst = True
|
|
||||||
return Result
|
|
||||||
|
|
||||||
# 检查是否有位域类型 (t.Bit)
|
|
||||||
if LeftInfo.IsBitField:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else t.CInt()
|
|
||||||
Result.IsBitField = True
|
|
||||||
Result.BitWidth = LeftInfo.BitWidth
|
|
||||||
return Result
|
|
||||||
if RightInfo.IsBitField:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else t.CInt()
|
|
||||||
Result.IsBitField = True
|
|
||||||
Result.BitWidth = RightInfo.BitWidth
|
|
||||||
return Result
|
|
||||||
|
|
||||||
# 处理字节序类型 (t.BigEndian, t.LittleEndian)
|
|
||||||
if LeftInfo.ByteOrder:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else t.CInt()
|
|
||||||
Result.ByteOrder = LeftInfo.ByteOrder
|
|
||||||
return Result
|
|
||||||
if RightInfo.ByteOrder:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else t.CInt()
|
|
||||||
Result.ByteOrder = RightInfo.ByteOrder
|
|
||||||
return Result
|
|
||||||
|
|
||||||
if LeftInfo.IsFuncPtr or RightInfo.IsFuncPtr:
|
|
||||||
Result = cls()
|
|
||||||
FuncPtrSide = LeftInfo if LeftInfo.IsFuncPtr else RightInfo
|
|
||||||
Result.IsFuncPtr = True
|
|
||||||
Result.FuncPtrParams = list(FuncPtrSide.FuncPtrParams)
|
|
||||||
Result.FuncPtrReturn = FuncPtrSide.FuncPtrReturn
|
|
||||||
if LeftInfo.Storage:
|
|
||||||
Result.Storage = LeftInfo.Storage
|
|
||||||
elif RightInfo.Storage:
|
|
||||||
Result.Storage = RightInfo.Storage
|
|
||||||
return Result
|
|
||||||
|
|
||||||
if LeftInfo.IsTypedef and RightInfo.BaseType:
|
|
||||||
if LeftInfo.BaseType and (not isinstance(LeftInfo.BaseType, (t._CTypedef,)) or LeftInfo.PtrCount > 0):
|
|
||||||
Result = LeftInfo.Copy()
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
if RightInfo.Storage:
|
|
||||||
Result.Storage = RightInfo.Storage
|
|
||||||
return Result
|
|
||||||
return RightInfo
|
|
||||||
if RightInfo.IsTypedef and LeftInfo.BaseType:
|
|
||||||
if RightInfo.BaseType and (not isinstance(RightInfo.BaseType, (t._CTypedef,)) or RightInfo.PtrCount > 0):
|
|
||||||
Result = RightInfo.Copy()
|
|
||||||
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
|
||||||
if LeftInfo.Storage:
|
|
||||||
Result.Storage = LeftInfo.Storage
|
|
||||||
return Result
|
|
||||||
return LeftInfo
|
|
||||||
|
|
||||||
if LeftInfo.BaseType:
|
|
||||||
return LeftInfo
|
|
||||||
elif RightInfo.BaseType:
|
|
||||||
return RightInfo
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _FromNode_Subscript(cls, Node: ast.Subscript, SymbolTable: dict) -> "CTypeInfo":
|
|
||||||
"""处理 ast.Subscript 节点"""
|
|
||||||
from lib.includes import t
|
|
||||||
|
|
||||||
base = Node.value
|
|
||||||
if isinstance(base, ast.Attribute):
|
|
||||||
if isinstance(base.value, ast.Name) and base.value.id == 't' and base.attr == 'Bit':
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.IsBitField = True
|
|
||||||
if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int):
|
|
||||||
Result.BitWidth = Node.slice.value
|
|
||||||
else:
|
|
||||||
Result.BitWidth = 1
|
|
||||||
return Result
|
|
||||||
if isinstance(base, ast.Name) and base.id == 'list':
|
|
||||||
slice_node = Node.slice
|
|
||||||
elts = []
|
|
||||||
if isinstance(slice_node, ast.Tuple):
|
|
||||||
elts = slice_node.elts
|
|
||||||
elif isinstance(slice_node, (ast.Attribute, ast.Name, ast.Subscript)):
|
|
||||||
elts = [slice_node]
|
|
||||||
if elts:
|
|
||||||
ElemInfo = cls.FromNode(elts[0], SymbolTable)
|
|
||||||
if ElemInfo and ElemInfo.BaseType:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = ElemInfo.BaseType
|
|
||||||
Result.PtrCount = ElemInfo.PtrCount
|
|
||||||
Result.ArrayDims = list(ElemInfo.ArrayDims)
|
|
||||||
if len(elts) >= 2:
|
|
||||||
count_val = cls.TryEvalConstExpr(elts[1], SymbolTable)
|
|
||||||
if count_val is not None and isinstance(count_val, int) and count_val > 0:
|
|
||||||
Result.ArrayDims.insert(0, str(count_val))
|
|
||||||
else:
|
|
||||||
Result.PtrCount += 1
|
|
||||||
if ElemInfo.IsPtr and not ElemInfo.ArrayDims:
|
|
||||||
Result.PtrCount = max(Result.PtrCount, 1)
|
|
||||||
return Result
|
|
||||||
if isinstance(base, ast.Attribute):
|
|
||||||
parts = []
|
|
||||||
current = base
|
|
||||||
while isinstance(current, ast.Attribute):
|
|
||||||
parts.insert(0, current.attr)
|
|
||||||
current = current.value
|
|
||||||
if isinstance(current, ast.Name):
|
|
||||||
parts.insert(0, current.id)
|
|
||||||
if parts and parts[0] == 't' and parts[-1] == t.CPtr.__name__:
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CVoid()
|
|
||||||
Result.PtrCount = 1
|
|
||||||
slice_node = Node.slice
|
|
||||||
if isinstance(slice_node, ast.Subscript):
|
|
||||||
InnerInfo = cls.FromNode(slice_node, SymbolTable)
|
|
||||||
if InnerInfo:
|
|
||||||
if InnerInfo.PtrCount > 0:
|
|
||||||
Result.PtrCount += InnerInfo.PtrCount
|
|
||||||
if InnerInfo.BaseType and not isinstance(InnerInfo.BaseType, t.CVoid):
|
|
||||||
Result.BaseType = InnerInfo.BaseType
|
|
||||||
elif isinstance(slice_node, ast.Attribute):
|
|
||||||
SliceInfo = cls.FromNode(slice_node, SymbolTable)
|
|
||||||
if SliceInfo:
|
|
||||||
if SliceInfo.IsPtr:
|
|
||||||
Result.PtrCount += SliceInfo.PtrCount
|
|
||||||
elif SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
|
|
||||||
Result.BaseType = SliceInfo.BaseType
|
|
||||||
elif isinstance(slice_node, ast.Name):
|
|
||||||
SliceType = getattr(t, slice_node.id, None)
|
|
||||||
if SliceType == t.CPtr:
|
|
||||||
Result.PtrCount += 1
|
|
||||||
else:
|
|
||||||
SliceInfo = cls.FromNode(slice_node, SymbolTable)
|
|
||||||
if SliceInfo and SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
|
|
||||||
Result.BaseType = SliceInfo.BaseType
|
|
||||||
return Result
|
|
||||||
if parts and parts[0] == 't' and parts[-1] == 'Callable':
|
|
||||||
Result = cls()
|
|
||||||
Result.IsFuncPtr = True
|
|
||||||
slice_node = Node.slice
|
|
||||||
if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2:
|
|
||||||
params_list = slice_node.elts[0]
|
|
||||||
return_node = slice_node.elts[1]
|
|
||||||
ParamTypes = []
|
|
||||||
if isinstance(params_list, ast.List):
|
|
||||||
for elt in params_list.elts:
|
|
||||||
ParamTypeInfo = cls.FromNode(elt, SymbolTable)
|
|
||||||
if ParamTypeInfo:
|
|
||||||
ParamTypes.append(('', ParamTypeInfo))
|
|
||||||
if not ParamTypes:
|
|
||||||
ParamTypes.append(('', cls.FromTypeName('void')))
|
|
||||||
Result.FuncPtrParams = ParamTypes
|
|
||||||
ReturnTypeInfo = cls.FromNode(return_node, SymbolTable)
|
|
||||||
Result.FuncPtrReturn = ReturnTypeInfo if ReturnTypeInfo else CTypeInfo.VoidTypeInfo()
|
|
||||||
return Result
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _FromNode_Attribute(cls, Node: ast.Attribute, SymbolTable: dict) -> "CTypeInfo":
|
|
||||||
"""处理 ast.Attribute 节点"""
|
|
||||||
from lib.includes import t
|
|
||||||
|
|
||||||
ModuleParts = []
|
|
||||||
Current = Node
|
|
||||||
while isinstance(Current, ast.Attribute):
|
|
||||||
ModuleParts.insert(0, Current.attr)
|
|
||||||
Current = Current.value
|
|
||||||
|
|
||||||
if isinstance(Current, ast.Name):
|
|
||||||
ModuleParts.insert(0, Current.id)
|
|
||||||
|
|
||||||
if len(ModuleParts) >= 2:
|
|
||||||
TypeName = ModuleParts[-1]
|
|
||||||
ModulePath = '.'.join(ModuleParts[:-1])
|
|
||||||
elif len(ModuleParts) == 1:
|
|
||||||
TypeName = ModuleParts[0]
|
|
||||||
ModulePath = None
|
|
||||||
else:
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
# 解析 import 别名: 如 import vpsdk.window as window -> window -> vpsdk.window
|
|
||||||
if ModulePath:
|
|
||||||
resolved = False
|
|
||||||
if hasattr(SymbolTable, 'translator'):
|
|
||||||
import_aliases = getattr(SymbolTable.translator, '_ImportAliases', {})
|
|
||||||
if ModulePath in import_aliases:
|
|
||||||
ModulePath = import_aliases[ModulePath]
|
|
||||||
resolved = True
|
|
||||||
if not resolved and ModulePath in SymbolTable:
|
|
||||||
entry = SymbolTable[ModulePath]
|
|
||||||
if isinstance(entry, CTypeInfo) and getattr(entry, 'IsModuleAlias', False):
|
|
||||||
resolved_name = getattr(entry, 'ResolvedModule', None)
|
|
||||||
if resolved_name:
|
|
||||||
ModulePath = resolved_name
|
|
||||||
|
|
||||||
if ModulePath == 't' or (ModulePath and ModulePath.startswith('t.')):
|
|
||||||
TypeClass = CTypeHelper.GetTModuleCType(TypeName)
|
|
||||||
if TypeClass is None:
|
|
||||||
TypeClass = getattr(t, TypeName, None)
|
|
||||||
if TypeClass is not None and TypeClass.HasPosition(t.CType.POINTER):
|
|
||||||
Info = cls()
|
|
||||||
Info.PtrCount = 1
|
|
||||||
if TypeClass == t.CArrayPtr:
|
|
||||||
Info.IsArrayPtr = True
|
|
||||||
Info.BaseType = t.CVoid
|
|
||||||
return Info
|
|
||||||
if TypeClass is not None and TypeClass.IsStorageClass():
|
|
||||||
Info = cls()
|
|
||||||
Info.Storage = TypeClass()
|
|
||||||
if TypeClass == t.State:
|
|
||||||
Info.IsState = True
|
|
||||||
Info.BaseType = t.CVoid()
|
|
||||||
return Info
|
|
||||||
if TypeClass is not None and TypeClass.IsTypeQualifier():
|
|
||||||
Info = cls()
|
|
||||||
if TypeClass == t.CConst:
|
|
||||||
Info.DataConst = True
|
|
||||||
elif TypeClass == t.CVolatile:
|
|
||||||
Info.DataVolatile = True
|
|
||||||
return Info
|
|
||||||
if (TypeClass is not None
|
|
||||||
and isinstance(TypeClass, type)
|
|
||||||
and issubclass(TypeClass, t.CType)
|
|
||||||
and TypeClass is not t.CType
|
|
||||||
and TypeClass.HasPosition(t.CType.BASE)):
|
|
||||||
if TypeClass == t.State:
|
|
||||||
Result = cls()
|
|
||||||
Result.IsState = True
|
|
||||||
Result.BaseType = t.CVoid()
|
|
||||||
return Result
|
|
||||||
Inst = TypeClass()
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = TypeClass
|
|
||||||
if hasattr(Inst, 'CName') and Inst.CName:
|
|
||||||
Result.Name = Inst.CName
|
|
||||||
if hasattr(Inst, 'IsSigned'):
|
|
||||||
Result.IsSigned = Inst.IsSigned
|
|
||||||
return Result
|
|
||||||
CNAME = CTypeHelper.GetCName(TypeName)
|
|
||||||
if CNAME:
|
|
||||||
return cls.FromTypeName(CNAME)
|
|
||||||
|
|
||||||
# 处理字节序类型
|
|
||||||
if TypeName == 'BigEndian':
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.ByteOrder = 'big'
|
|
||||||
return Result
|
|
||||||
if TypeName == 'LittleEndian':
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.ByteOrder = 'little'
|
|
||||||
return Result
|
|
||||||
|
|
||||||
FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName
|
|
||||||
|
|
||||||
if TypeName in SymbolTable:
|
|
||||||
Entry = SymbolTable[TypeName]
|
|
||||||
if Entry and getattr(Entry, 'IsTypedef', None):
|
|
||||||
Resolved = Entry.Copy()
|
|
||||||
if Resolved.BaseType is None:
|
|
||||||
Resolved.BaseType = t._CTypedef(TypeName)
|
|
||||||
return Resolved
|
|
||||||
if Entry and getattr(Entry, 'IsEnum', None):
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.IsEnum = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
if Entry and getattr(Entry, 'IsExceptionClass', None):
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t.CInt()
|
|
||||||
Result.IsExceptionClass = True
|
|
||||||
Result.Name = TypeName
|
|
||||||
return Result
|
|
||||||
if Entry:
|
|
||||||
Result = Entry.Copy()
|
|
||||||
if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name):
|
|
||||||
Result.BaseType = t.CStruct(name=TypeName)
|
|
||||||
Result.IsStruct = True
|
|
||||||
return Result
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
if FullName in SymbolTable:
|
|
||||||
Info = SymbolTable[FullName]
|
|
||||||
if Info and Info.IsTypedef:
|
|
||||||
OriginalType = Info.get('OriginalType', '')
|
|
||||||
if OriginalType and 'typedef' in OriginalType:
|
|
||||||
parts = OriginalType.split()
|
|
||||||
if len(parts) >= 2:
|
|
||||||
BaseType_name = parts[1]
|
|
||||||
if not BaseType_name.startswith('C'):
|
|
||||||
BaseType_name = 'C' + BaseType_name
|
|
||||||
CNAME = CTypeHelper.GetCName(BaseType_name)
|
|
||||||
if CNAME:
|
|
||||||
return cls.FromTypeName(CNAME)
|
|
||||||
Result = cls()
|
|
||||||
Result.BaseType = t._CTypedef(TypeName)
|
|
||||||
Result.IsTypedef = True
|
|
||||||
return Result
|
|
||||||
if Info:
|
|
||||||
Result = Info.Copy()
|
|
||||||
if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name):
|
|
||||||
Result.BaseType = t.CStruct(name=TypeName)
|
|
||||||
Result.IsStruct = True
|
|
||||||
return Result
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _HandleArraySubscript(cls, Node, SymbolTable):
|
|
||||||
if not isinstance(Node, ast.Subscript):
|
|
||||||
return None
|
|
||||||
dims = []
|
|
||||||
current = Node
|
|
||||||
while isinstance(current, ast.Subscript):
|
|
||||||
if isinstance(current.slice, ast.Constant) and isinstance(current.slice.value, int):
|
|
||||||
dims.insert(0, str(current.slice.value))
|
|
||||||
elif isinstance(current.slice, ast.Name):
|
|
||||||
dims.insert(0, current.slice.id)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
current = current.value
|
|
||||||
base_info = cls.FromNode(current, SymbolTable)
|
|
||||||
if base_info and base_info.BaseType:
|
|
||||||
base_info.ArrayDims = dims
|
|
||||||
return base_info
|
|
||||||
return None
|
|
||||||
|
|
||||||
def Copy(self) -> "CTypeInfo":
|
def Copy(self) -> "CTypeInfo":
|
||||||
NewInfo = CTypeInfo()
|
NewInfo = CTypeInfo()
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class ClassHandle(BaseHandle):
|
|||||||
ExcTypeInfo.Name = ClassName
|
ExcTypeInfo.Name = ClassName
|
||||||
ExcTypeInfo.IsExceptionClass = True
|
ExcTypeInfo.IsExceptionClass = True
|
||||||
ExcTypeInfo.value = code
|
ExcTypeInfo.value = code
|
||||||
self.Trans.SymbolTable[ClassName] = ExcTypeInfo
|
self.Trans.SymbolTable.insert(ClassName, ExcTypeInfo)
|
||||||
|
|
||||||
def _is_generic_class(self, Node):
|
def _is_generic_class(self, Node):
|
||||||
if hasattr(Node, 'type_params') and Node.type_params:
|
if hasattr(Node, 'type_params') and Node.type_params:
|
||||||
@@ -660,7 +660,7 @@ class ClassHandle(BaseHandle):
|
|||||||
UnionNode = CTypeInfo()
|
UnionNode = CTypeInfo()
|
||||||
UnionNode.Name = ClassName
|
UnionNode.Name = ClassName
|
||||||
UnionNode.IsUnion = True
|
UnionNode.IsUnion = True
|
||||||
self.Trans.SymbolTable[ClassName] = UnionNode
|
self.Trans.SymbolTable.insert(ClassName, UnionNode)
|
||||||
|
|
||||||
def _EmitREnumLlvm(self, Node, Gen):
|
def _EmitREnumLlvm(self, Node, Gen):
|
||||||
ClassName = Node.name
|
ClassName = Node.name
|
||||||
@@ -767,14 +767,14 @@ class ClassHandle(BaseHandle):
|
|||||||
MemberNode.EnumName = ClassName
|
MemberNode.EnumName = ClassName
|
||||||
MemberNode.Lineno = lineno
|
MemberNode.Lineno = lineno
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.Trans.SymbolTable[VariantName] = MemberNode
|
self.Trans.SymbolTable.insert(VariantName, MemberNode)
|
||||||
RenumTypeInfo = CTypeInfo()
|
RenumTypeInfo = CTypeInfo()
|
||||||
RenumTypeInfo.Name = ClassName
|
RenumTypeInfo.Name = ClassName
|
||||||
RenumTypeInfo.BaseType = t.REnum(ClassName)
|
RenumTypeInfo.BaseType = t.REnum(ClassName)
|
||||||
RenumTypeInfo.IsRenum = True
|
RenumTypeInfo.IsRenum = True
|
||||||
RenumTypeInfo.IsEnum = True
|
RenumTypeInfo.IsEnum = True
|
||||||
RenumTypeInfo.RenumVariants = variant_names
|
RenumTypeInfo.RenumVariants = variant_names
|
||||||
self.Trans.SymbolTable[ClassName] = RenumTypeInfo
|
self.Trans.SymbolTable.insert(ClassName, RenumTypeInfo)
|
||||||
|
|
||||||
def _RegisterEnumMembers(self, Node):
|
def _RegisterEnumMembers(self, Node):
|
||||||
ClassName = Node.name
|
ClassName = Node.name
|
||||||
@@ -782,7 +782,7 @@ class ClassHandle(BaseHandle):
|
|||||||
EnumTypeInfo.Name = ClassName
|
EnumTypeInfo.Name = ClassName
|
||||||
EnumTypeInfo.BaseType = t.CEnum(ClassName)
|
EnumTypeInfo.BaseType = t.CEnum(ClassName)
|
||||||
EnumTypeInfo.IsEnum = True
|
EnumTypeInfo.IsEnum = True
|
||||||
self.Trans.SymbolTable[ClassName] = EnumTypeInfo
|
self.Trans.SymbolTable.insert(ClassName, EnumTypeInfo)
|
||||||
from lib.core.Exportable import EnumMember as ExportEnumMember
|
from lib.core.Exportable import EnumMember as ExportEnumMember
|
||||||
enum_export = self.Trans.Exportable.add_enum(
|
enum_export = self.Trans.Exportable.add_enum(
|
||||||
name=ClassName,
|
name=ClassName,
|
||||||
@@ -806,7 +806,7 @@ class ClassHandle(BaseHandle):
|
|||||||
next_enum_value = value + 1
|
next_enum_value = value + 1
|
||||||
elif isinstance(item.value, ast.Name):
|
elif isinstance(item.value, ast.Name):
|
||||||
value = item.value.id
|
value = item.value.id
|
||||||
if value in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(value):
|
||||||
ref_info = self.Trans.SymbolTable[value]
|
ref_info = self.Trans.SymbolTable[value]
|
||||||
if ref_info.value is not None and isinstance(ref_info.value, int):
|
if ref_info.value is not None and isinstance(ref_info.value, int):
|
||||||
next_enum_value = ref_info.value + 1
|
next_enum_value = ref_info.value + 1
|
||||||
@@ -820,7 +820,7 @@ class ClassHandle(BaseHandle):
|
|||||||
MemberNode.EnumName = ClassName
|
MemberNode.EnumName = ClassName
|
||||||
MemberNode.Lineno = item.lineno
|
MemberNode.Lineno = item.lineno
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.Trans.SymbolTable[VarName] = MemberNode
|
self.Trans.SymbolTable.insert(VarName, MemberNode)
|
||||||
enum_export.members.append(ExportEnumMember(
|
enum_export.members.append(ExportEnumMember(
|
||||||
name=VarName,
|
name=VarName,
|
||||||
value=value,
|
value=value,
|
||||||
@@ -840,7 +840,7 @@ class ClassHandle(BaseHandle):
|
|||||||
next_enum_value = value + 1
|
next_enum_value = value + 1
|
||||||
elif isinstance(item.value, ast.Name):
|
elif isinstance(item.value, ast.Name):
|
||||||
value = item.value.id
|
value = item.value.id
|
||||||
if value in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(value):
|
||||||
ref_info = self.Trans.SymbolTable[value]
|
ref_info = self.Trans.SymbolTable[value]
|
||||||
if ref_info.value is not None and isinstance(ref_info.value, int):
|
if ref_info.value is not None and isinstance(ref_info.value, int):
|
||||||
next_enum_value = ref_info.value + 1
|
next_enum_value = ref_info.value + 1
|
||||||
@@ -854,7 +854,7 @@ class ClassHandle(BaseHandle):
|
|||||||
MemberNode.EnumName = ClassName
|
MemberNode.EnumName = ClassName
|
||||||
MemberNode.Lineno = item.lineno
|
MemberNode.Lineno = item.lineno
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.Trans.SymbolTable[VarName] = MemberNode
|
self.Trans.SymbolTable.insert(VarName, MemberNode)
|
||||||
enum_export.members.append(ExportEnumMember(
|
enum_export.members.append(ExportEnumMember(
|
||||||
name=VarName,
|
name=VarName,
|
||||||
value=value,
|
value=value,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class DeleteHandle(BaseHandle):
|
|||||||
ClassName = self.Trans._CurrentCpythonObjectClass
|
ClassName = self.Trans._CurrentCpythonObjectClass
|
||||||
if ClassName:
|
if ClassName:
|
||||||
PropKey = f'{ClassName}.{AttrName}'
|
PropKey = f'{ClassName}.{AttrName}'
|
||||||
PropInfo = self.Trans.SymbolTable.get(PropKey)
|
PropInfo = self.Trans.SymbolTable.lookup(PropKey)
|
||||||
if PropInfo and 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')
|
SelfVar = Gen._get_var_ptr('self')
|
||||||
if SelfVar:
|
if SelfVar:
|
||||||
@@ -53,7 +53,7 @@ class DeleteHandle(BaseHandle):
|
|||||||
ClassName = self.Trans.ExprHandler._get_var_class(target.value, Gen)
|
ClassName = self.Trans.ExprHandler._get_var_class(target.value, Gen)
|
||||||
if ClassName:
|
if ClassName:
|
||||||
PropKey = f'{ClassName}.{AttrName}'
|
PropKey = f'{ClassName}.{AttrName}'
|
||||||
PropInfo = self.Trans.SymbolTable.get(PropKey)
|
PropInfo = self.Trans.SymbolTable.lookup(PropKey)
|
||||||
if PropInfo and 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)
|
obj_val = self.Trans.ExprHandler.HandleExprLlvm(target.value)
|
||||||
if obj_val:
|
if obj_val:
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ class ExprHandle(BaseHandle):
|
|||||||
# 如果 _define_constants 中没有,尝试从符号表查找
|
# 如果 _define_constants 中没有,尝试从符号表查找
|
||||||
if VarName not in getattr(Gen, '_define_constants', {}):
|
if VarName not in getattr(Gen, '_define_constants', {}):
|
||||||
try:
|
try:
|
||||||
sym_info = self.translator.SymbolTable.get(VarName)
|
sym_info = self.translator.SymbolTable.lookup(VarName)
|
||||||
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
|
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
|
||||||
val = sym_info.DefineValue
|
val = sym_info.DefineValue
|
||||||
if isinstance(val, int):
|
if isinstance(val, int):
|
||||||
@@ -398,7 +398,7 @@ class ExprHandle(BaseHandle):
|
|||||||
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
||||||
if VarName == 'True' or VarName == 'False':
|
if VarName == 'True' or VarName == 'False':
|
||||||
return ir.Constant(ir.IntType(32), 1 if VarName == 'True' else 0)
|
return ir.Constant(ir.IntType(32), 1 if VarName == 'True' else 0)
|
||||||
if VarName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(VarName):
|
||||||
SymInfo = self.Trans.SymbolTable[VarName]
|
SymInfo = self.Trans.SymbolTable[VarName]
|
||||||
if SymInfo.IsEnumMember and isinstance(SymInfo.value, int):
|
if SymInfo.IsEnumMember and isinstance(SymInfo.value, int):
|
||||||
return ir.Constant(ir.IntType(32), SymInfo.value)
|
return ir.Constant(ir.IntType(32), SymInfo.value)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
if key not in PossibleKeys:
|
if key not in PossibleKeys:
|
||||||
PossibleKeys.append(key)
|
PossibleKeys.append(key)
|
||||||
for lookup_key in PossibleKeys:
|
for lookup_key in PossibleKeys:
|
||||||
SymInfo = self.Trans.SymbolTable.get(lookup_key)
|
SymInfo = self.Trans.SymbolTable.lookup(lookup_key)
|
||||||
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
|
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
|
||||||
return self._make_define_constant(Gen, SymInfo.DefineValue)
|
return self._make_define_constant(Gen, SymInfo.DefineValue)
|
||||||
# 也检查 _define_constants
|
# 也检查 _define_constants
|
||||||
@@ -104,10 +104,9 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
def _lookup_module_global(self, Gen, VarName, AttrName):
|
def _lookup_module_global(self, Gen, VarName, AttrName):
|
||||||
"""在模块全局变量中查找 import 的属性"""
|
"""在模块全局变量中查找 import 的属性"""
|
||||||
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
|
||||||
if not imported_modules:
|
if not imported_modules:
|
||||||
return None
|
return None
|
||||||
resolved_mod = import_aliases.get(VarName, VarName)
|
resolved_mod = self.Trans.SymbolTable.resolve_alias(VarName)
|
||||||
if VarName not in imported_modules and resolved_mod not in imported_modules:
|
if VarName not in imported_modules and resolved_mod not in imported_modules:
|
||||||
return None
|
return None
|
||||||
PossibleKeys = [f"{VarName}.{AttrName}", AttrName]
|
PossibleKeys = [f"{VarName}.{AttrName}", AttrName]
|
||||||
@@ -201,7 +200,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
return None
|
return None
|
||||||
# 检查 property getter
|
# 检查 property getter
|
||||||
PropKey = f'{ClassName}.{Node.attr}'
|
PropKey = f'{ClassName}.{Node.attr}'
|
||||||
PropInfo = self.Trans.SymbolTable.get(PropKey)
|
PropInfo = self.Trans.SymbolTable.lookup(PropKey)
|
||||||
if PropInfo and 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')
|
SelfVar = Gen._get_var_ptr('self')
|
||||||
if SelfVar:
|
if SelfVar:
|
||||||
@@ -233,10 +232,10 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
|
|
||||||
def _handle_attr_enum(self, Node, VarName):
|
def _handle_attr_enum(self, Node, VarName):
|
||||||
"""处理枚举成员访问 (VarName 是枚举类型名)"""
|
"""处理枚举成员访问 (VarName 是枚举类型名)"""
|
||||||
SymInfo = self.Trans.SymbolTable.get(VarName)
|
SymInfo = self.Trans.SymbolTable.lookup(VarName)
|
||||||
if not SymInfo or not SymInfo.IsEnum:
|
if not SymInfo or not SymInfo.IsEnum:
|
||||||
return None
|
return None
|
||||||
if Node.attr in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(Node.attr):
|
||||||
MemberInfo = self.Trans.SymbolTable[Node.attr]
|
MemberInfo = self.Trans.SymbolTable[Node.attr]
|
||||||
if MemberInfo.IsEnumMember and MemberInfo.EnumName == VarName:
|
if MemberInfo.IsEnumMember and MemberInfo.EnumName == VarName:
|
||||||
if isinstance(MemberInfo.value, int):
|
if isinstance(MemberInfo.value, int):
|
||||||
@@ -284,7 +283,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
|
|
||||||
# 检查 property getter
|
# 检查 property getter
|
||||||
PropKey = f'{ClassName}.{AttrName}'
|
PropKey = f'{ClassName}.{AttrName}'
|
||||||
PropInfo = self.Trans.SymbolTable.get(PropKey)
|
PropInfo = self.Trans.SymbolTable.lookup(PropKey)
|
||||||
if PropInfo and 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)
|
ObjVal = self.HandleExprLlvm(Node.value)
|
||||||
GetterFunc = Gen._get_function(PropKey)
|
GetterFunc = Gen._get_function(PropKey)
|
||||||
@@ -294,7 +293,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
return Gen.builder.call(GetterFunc, [ObjVal], name=f"prop_{PropKey}")
|
return Gen.builder.call(GetterFunc, [ObjVal], name=f"prop_{PropKey}")
|
||||||
|
|
||||||
# 获取类型信息
|
# 获取类型信息
|
||||||
TypeInfo = self.Trans.SymbolTable.get(ClassName)
|
TypeInfo = self.Trans.SymbolTable.lookup(ClassName)
|
||||||
IsUnion = TypeInfo.IsUnion if TypeInfo else False
|
IsUnion = TypeInfo.IsUnion if TypeInfo else False
|
||||||
IsCenum = TypeInfo.IsEnum if TypeInfo else False
|
IsCenum = TypeInfo.IsEnum if TypeInfo else False
|
||||||
IsRenum = TypeInfo.IsRenum if TypeInfo else False
|
IsRenum = TypeInfo.IsRenum if TypeInfo else False
|
||||||
@@ -320,7 +319,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
# CEnum 处理
|
# CEnum 处理
|
||||||
if IsCenum:
|
if IsCenum:
|
||||||
for qname in (f"{ClassName}.{AttrName}", f"{ClassName}_{AttrName}"):
|
for qname in (f"{ClassName}.{AttrName}", f"{ClassName}_{AttrName}"):
|
||||||
if qname in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(qname):
|
||||||
info = self.Trans.SymbolTable[qname]
|
info = self.Trans.SymbolTable[qname]
|
||||||
if info.IsEnumMember and isinstance(info.value, int):
|
if info.IsEnumMember and isinstance(info.value, int):
|
||||||
return ir.Constant(ir.IntType(32), info.value)
|
return ir.Constant(ir.IntType(32), info.value)
|
||||||
@@ -817,8 +816,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
ClassName = Gen.global_struct_class.get(VarName)
|
ClassName = Gen.global_struct_class.get(VarName)
|
||||||
if not ClassName:
|
if not ClassName:
|
||||||
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
resolved_mod = self.Trans.SymbolTable.resolve_alias(VarName)
|
||||||
resolved_mod = import_aliases.get(VarName, VarName)
|
|
||||||
if imported_modules and (VarName in imported_modules or resolved_mod in imported_modules):
|
if imported_modules and (VarName in imported_modules or resolved_mod in imported_modules):
|
||||||
AttrName = Node.attr
|
AttrName = Node.attr
|
||||||
ModuleSha1Map = getattr(Gen, 'ModuleSha1Map', {})
|
ModuleSha1Map = getattr(Gen, 'ModuleSha1Map', {})
|
||||||
@@ -1035,7 +1033,6 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
||||||
if not imported_modules:
|
if not imported_modules:
|
||||||
return None
|
return None
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
|
||||||
parts = self._build_attr_path(Node)
|
parts = self._build_attr_path(Node)
|
||||||
if len(parts) < 2:
|
if len(parts) < 2:
|
||||||
return None
|
return None
|
||||||
@@ -1046,7 +1043,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
possible_keys.append(full_path)
|
possible_keys.append(full_path)
|
||||||
if module_parts:
|
if module_parts:
|
||||||
ModulePath = '.'.join(module_parts)
|
ModulePath = '.'.join(module_parts)
|
||||||
resolved_first = import_aliases.get(module_parts[0], module_parts[0])
|
resolved_first = self.Trans.SymbolTable.resolve_alias(module_parts[0])
|
||||||
if resolved_first != module_parts[0]:
|
if resolved_first != module_parts[0]:
|
||||||
resolved_parts = [resolved_first] + module_parts[1:]
|
resolved_parts = [resolved_first] + module_parts[1:]
|
||||||
resolved_path = '.'.join(resolved_parts)
|
resolved_path = '.'.join(resolved_parts)
|
||||||
@@ -1061,7 +1058,7 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
if key not in possible_keys:
|
if key not in possible_keys:
|
||||||
possible_keys.append(key)
|
possible_keys.append(key)
|
||||||
for lookup_key in possible_keys:
|
for lookup_key in possible_keys:
|
||||||
SymInfo = self.Trans.SymbolTable.get(lookup_key)
|
SymInfo = self.Trans.SymbolTable.lookup(lookup_key)
|
||||||
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
|
if SymInfo and SymInfo.IsDefine and SymInfo.DefineValue is not None:
|
||||||
val = SymInfo.DefineValue
|
val = SymInfo.DefineValue
|
||||||
if isinstance(val, int):
|
if isinstance(val, int):
|
||||||
@@ -1077,17 +1074,16 @@ class ExprAttrHandle(BaseHandle):
|
|||||||
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
imported_modules = getattr(self.Trans, '_ImportedModules', None)
|
||||||
if not imported_modules:
|
if not imported_modules:
|
||||||
return None
|
return None
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
resolved_module = self.Trans.SymbolTable.resolve_alias(module_alias)
|
||||||
resolved_module = import_aliases.get(module_alias, module_alias)
|
|
||||||
if resolved_module not in imported_modules and module_alias not in imported_modules:
|
if resolved_module not in imported_modules and module_alias not in imported_modules:
|
||||||
return None
|
return None
|
||||||
enum_keys = [enum_class_name, f"{resolved_module}.{enum_class_name}"]
|
enum_keys = [enum_class_name, f"{resolved_module}.{enum_class_name}"]
|
||||||
for enum_key in enum_keys:
|
for enum_key in enum_keys:
|
||||||
if enum_key in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(enum_key):
|
||||||
SymInfo = self.Trans.SymbolTable[enum_key]
|
SymInfo = self.Trans.SymbolTable[enum_key]
|
||||||
if SymInfo.IsEnum:
|
if SymInfo.IsEnum:
|
||||||
for qname in (f"{enum_key}.{member_name}", f"{enum_key}_{member_name}"):
|
for qname in (f"{enum_key}.{member_name}", f"{enum_key}_{member_name}"):
|
||||||
if qname in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(qname):
|
||||||
info = self.Trans.SymbolTable[qname]
|
info = self.Trans.SymbolTable[qname]
|
||||||
if info.IsEnumMember and isinstance(info.value, int):
|
if info.IsEnumMember and isinstance(info.value, int):
|
||||||
return ir.Constant(ir.IntType(32), info.value)
|
return ir.Constant(ir.IntType(32), info.value)
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ class ExprBuiltinHandle(BaseHandle):
|
|||||||
type_info = Gen.var_type_info[arg_name]
|
type_info = Gen.var_type_info[arg_name]
|
||||||
if isinstance(type_info, dict) and type_info.get('type') == 'enum':
|
if isinstance(type_info, dict) and type_info.get('type') == 'enum':
|
||||||
enum_type_name = type_info.get('name')
|
enum_type_name = type_info.get('name')
|
||||||
if not enum_type_name and arg_name in self.Trans.SymbolTable:
|
if not enum_type_name and self.Trans.SymbolTable.has(arg_name):
|
||||||
TypeInfo = self.Trans.SymbolTable[arg_name]
|
TypeInfo = self.Trans.SymbolTable[arg_name]
|
||||||
if TypeInfo.IsEnum:
|
if TypeInfo.IsEnum:
|
||||||
enum_type_name = arg_name
|
enum_type_name = arg_name
|
||||||
@@ -537,7 +537,7 @@ class ExprBuiltinHandle(BaseHandle):
|
|||||||
enum_class_name = None
|
enum_class_name = None
|
||||||
if isinstance(arg.value, ast.Name):
|
if isinstance(arg.value, ast.Name):
|
||||||
LastPart = arg.attr
|
LastPart = arg.attr
|
||||||
if LastPart in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(LastPart):
|
||||||
AttrInfo = self.Trans.SymbolTable[LastPart]
|
AttrInfo = self.Trans.SymbolTable[LastPart]
|
||||||
if AttrInfo.IsEnumMember and AttrInfo.EnumName:
|
if AttrInfo.IsEnumMember and AttrInfo.EnumName:
|
||||||
enum_type_name = AttrInfo.EnumName
|
enum_type_name = AttrInfo.EnumName
|
||||||
@@ -552,7 +552,7 @@ class ExprBuiltinHandle(BaseHandle):
|
|||||||
qualified_name_under = f"{enum_class_name}_{LastPart}"
|
qualified_name_under = f"{enum_class_name}_{LastPart}"
|
||||||
enum_member_found = None
|
enum_member_found = None
|
||||||
for qname in (qualified_name_dot, qualified_name_under):
|
for qname in (qualified_name_dot, qualified_name_under):
|
||||||
if qname in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(qname):
|
||||||
info = self.Trans.SymbolTable[qname]
|
info = self.Trans.SymbolTable[qname]
|
||||||
if info.IsEnumMember and info.EnumName == enum_class_name:
|
if info.IsEnumMember and info.EnumName == enum_class_name:
|
||||||
enum_member_found = info
|
enum_member_found = info
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return self._HandleTypeLlvm(Node)
|
return self._HandleTypeLlvm(Node)
|
||||||
if Gen._has_function(FuncName):
|
if Gen._has_function(FuncName):
|
||||||
return self._HandleClosureCallLlvm(Node, FuncName)
|
return self._HandleClosureCallLlvm(Node, FuncName)
|
||||||
if FuncName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FuncName):
|
||||||
SymInfo = self.Trans.SymbolTable[FuncName]
|
SymInfo = self.Trans.SymbolTable[FuncName]
|
||||||
if SymInfo.IsEnum:
|
if SymInfo.IsEnum:
|
||||||
if Node.args:
|
if Node.args:
|
||||||
@@ -430,12 +430,12 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return self._HandleSizeofLlvm(SizeofNode)
|
return self._HandleSizeofLlvm(SizeofNode)
|
||||||
ModulePath = self._get_ModulePath(Node.func.value)
|
ModulePath = self._get_ModulePath(Node.func.value)
|
||||||
if ModulePath:
|
if ModulePath:
|
||||||
aliases = getattr(self.Trans, '_ImportAliases', {})
|
|
||||||
first_part = ModulePath.split('.')[0]
|
first_part = ModulePath.split('.')[0]
|
||||||
if first_part in aliases:
|
resolved_first = self.Trans.SymbolTable.resolve_alias(first_part)
|
||||||
ModulePath = aliases[first_part] + ModulePath[len(first_part):]
|
if resolved_first != first_part:
|
||||||
|
ModulePath = resolved_first + 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_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 self.Trans.SymbolTable[Node.func.value.id].IsStruct))
|
is_class_name = isinstance(Node.func.value, ast.Name) and (Node.func.value.id in Gen.structs or self.Trans.SymbolTable.is_struct(Node.func.value.id))
|
||||||
if is_instance_var and not is_class_name:
|
if is_instance_var and not is_class_name:
|
||||||
return self._HandleMethodCallLlvm(Node)
|
return self._HandleMethodCallLlvm(Node)
|
||||||
FuncAttr = Node.func.attr
|
FuncAttr = Node.func.attr
|
||||||
@@ -445,7 +445,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return result
|
return result
|
||||||
if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and FuncAttr in self.Trans.ClassHandler._generic_class_templates:
|
if hasattr(self.Trans.ClassHandler, '_generic_class_templates') and FuncAttr in self.Trans.ClassHandler._generic_class_templates:
|
||||||
return self._HandleGenericClassNewLlvm(Node, FuncAttr)
|
return self._HandleGenericClassNewLlvm(Node, FuncAttr)
|
||||||
if FuncAttr in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FuncAttr):
|
||||||
SymInfo = self.Trans.SymbolTable[FuncAttr]
|
SymInfo = self.Trans.SymbolTable[FuncAttr]
|
||||||
if SymInfo.IsStruct:
|
if SymInfo.IsStruct:
|
||||||
if FuncAttr not in Gen.structs:
|
if FuncAttr not in Gen.structs:
|
||||||
@@ -456,14 +456,14 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return result
|
return result
|
||||||
if SymInfo.IsEnumMember and SymInfo.EnumName:
|
if SymInfo.IsEnumMember and SymInfo.EnumName:
|
||||||
EnumName = SymInfo.EnumName
|
EnumName = SymInfo.EnumName
|
||||||
if EnumName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(EnumName):
|
||||||
EnumInfo = self.Trans.SymbolTable[EnumName]
|
EnumInfo = self.Trans.SymbolTable[EnumName]
|
||||||
if EnumInfo.IsRenum:
|
if EnumInfo.IsRenum:
|
||||||
result = self._HandleREnumConstructLlvm(Node, EnumName, FuncAttr, SymInfo.value)
|
result = self._HandleREnumConstructLlvm(Node, EnumName, FuncAttr, SymInfo.value)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
||||||
if FullAttrKey in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FullAttrKey):
|
||||||
SymInfo = self.Trans.SymbolTable[FullAttrKey]
|
SymInfo = self.Trans.SymbolTable[FullAttrKey]
|
||||||
if SymInfo.IsStruct:
|
if SymInfo.IsStruct:
|
||||||
if FuncAttr not in Gen.structs:
|
if FuncAttr not in Gen.structs:
|
||||||
@@ -478,7 +478,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
||||||
if FullAttrKey in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FullAttrKey):
|
||||||
SymInfo = self.Trans.SymbolTable[FullAttrKey]
|
SymInfo = self.Trans.SymbolTable[FullAttrKey]
|
||||||
if SymInfo.IsTypedef:
|
if SymInfo.IsTypedef:
|
||||||
return ir.Constant(ir.IntType(32), 0)
|
return ir.Constant(ir.IntType(32), 0)
|
||||||
@@ -533,7 +533,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
raise Exception(f"Undefined method: 't.{FuncAttr}'")
|
raise Exception(f"Undefined method: 't.{FuncAttr}'")
|
||||||
if isinstance(Node.func.value, ast.Attribute):
|
if isinstance(Node.func.value, ast.Attribute):
|
||||||
inner_attr = Node.func.value.attr
|
inner_attr = Node.func.value.attr
|
||||||
if inner_attr in Gen.structs or (inner_attr in self.Trans.SymbolTable and self.Trans.SymbolTable[inner_attr].IsStruct):
|
if inner_attr in Gen.structs or self.Trans.SymbolTable.is_struct(inner_attr):
|
||||||
static_result = self._HandleStaticMethodCallLlvm(Node, inner_attr, FuncAttr)
|
static_result = self._HandleStaticMethodCallLlvm(Node, inner_attr, FuncAttr)
|
||||||
if static_result is not None:
|
if static_result is not None:
|
||||||
return static_result
|
return static_result
|
||||||
@@ -557,22 +557,21 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return Gen.builder.call(Gen._get_function(mangled_name), CallArgs, name=f"call_{FuncAttr}")
|
return Gen.builder.call(Gen._get_function(mangled_name), CallArgs, name=f"call_{FuncAttr}")
|
||||||
if MethodResult is None or IsZeroResult:
|
if MethodResult is None or IsZeroResult:
|
||||||
imported = getattr(self.Trans, '_ImportedModules', set())
|
imported = getattr(self.Trans, '_ImportedModules', set())
|
||||||
aliases = getattr(self.Trans, '_ImportAliases', {})
|
|
||||||
ModuleSha1Map = getattr(Gen, 'ModuleSha1Map', {})
|
ModuleSha1Map = getattr(Gen, 'ModuleSha1Map', {})
|
||||||
IsKnown = (ModulePath in imported or ModulePath in aliases or
|
IsKnown = (ModulePath in imported or ModulePath in self.Trans.SymbolTable.import_aliases or
|
||||||
ModulePath in ModuleSha1Map)
|
ModulePath in ModuleSha1Map)
|
||||||
if not IsKnown and ModulePath and '.' in ModulePath:
|
if not IsKnown and ModulePath and '.' in ModulePath:
|
||||||
LastPart = ModulePath.split('.')[-1]
|
LastPart = ModulePath.split('.')[-1]
|
||||||
IsKnown = (LastPart in imported or LastPart in aliases or
|
IsKnown = (LastPart in imported or LastPart in self.Trans.SymbolTable.import_aliases or
|
||||||
LastPart in ModuleSha1Map)
|
LastPart in ModuleSha1Map)
|
||||||
# 最后尝试: 用 FuncAttr 直接查找 Gen.functions(_find_function 会遍历 SHA1 前缀)
|
# 最后尝试: 用 FuncAttr 直接查找 Gen.functions(_find_function 会遍历 SHA1 前缀)
|
||||||
if FuncAttr and ModulePath and ModulePath not in {'t', 'c'}:
|
if FuncAttr and ModulePath and ModulePath not in {'t', 'c'}:
|
||||||
# 先检查 FuncAttr 是否是函数/变量,如果是则跳过 struct 声明
|
# 先检查 FuncAttr 是否是函数/变量,如果是则跳过 struct 声明
|
||||||
_attr_sym = self.Trans.SymbolTable.get(FuncAttr)
|
_attr_sym = self.Trans.SymbolTable.lookup(FuncAttr)
|
||||||
_is_func_or_var = _attr_sym and (_attr_sym.IsFunction or _attr_sym.IsVariable)
|
_is_func_or_var = _attr_sym and (_attr_sym.IsFunction or _attr_sym.IsVariable)
|
||||||
if not _is_func_or_var and ModulePath:
|
if not _is_func_or_var and ModulePath:
|
||||||
_full_key = f"{ModulePath}.{FuncAttr}"
|
_full_key = f"{ModulePath}.{FuncAttr}"
|
||||||
_full_sym = self.Trans.SymbolTable.get(_full_key)
|
_full_sym = self.Trans.SymbolTable.lookup(_full_key)
|
||||||
if _full_sym and (_full_sym.IsFunction or _full_sym.IsVariable):
|
if _full_sym and (_full_sym.IsFunction or _full_sym.IsVariable):
|
||||||
_is_func_or_var = True
|
_is_func_or_var = True
|
||||||
# 优先检查 FuncAttr 是否为 struct/类构造器
|
# 优先检查 FuncAttr 是否为 struct/类构造器
|
||||||
@@ -585,7 +584,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
# 检查 FullAttrKey 是否为 struct(如 hashlib.md5)
|
# 检查 FullAttrKey 是否为 struct(如 hashlib.md5)
|
||||||
if ModulePath:
|
if ModulePath:
|
||||||
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
FullAttrKey = f"{ModulePath}.{FuncAttr}"
|
||||||
if FullAttrKey in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FullAttrKey):
|
||||||
FullSymInfo = self.Trans.SymbolTable[FullAttrKey]
|
FullSymInfo = self.Trans.SymbolTable[FullAttrKey]
|
||||||
if FullSymInfo.IsStruct or FullSymInfo.IsCpythonObject:
|
if FullSymInfo.IsStruct or FullSymInfo.IsCpythonObject:
|
||||||
if FuncAttr not in Gen.structs:
|
if FuncAttr not in Gen.structs:
|
||||||
@@ -648,7 +647,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
def _ensure_struct_declared(self, class_name):
|
def _ensure_struct_declared(self, class_name):
|
||||||
Gen = self.Trans.LlvmGen
|
Gen = self.Trans.LlvmGen
|
||||||
# 如果名称是函数或变量,不应创建 struct
|
# 如果名称是函数或变量,不应创建 struct
|
||||||
SymInfo = self.Trans.SymbolTable.get(class_name)
|
SymInfo = self.Trans.SymbolTable.lookup(class_name)
|
||||||
if SymInfo and (SymInfo.IsFunction or SymInfo.IsVariable):
|
if SymInfo and (SymInfo.IsFunction or SymInfo.IsVariable):
|
||||||
return
|
return
|
||||||
if class_name in Gen.structs:
|
if class_name in Gen.structs:
|
||||||
@@ -660,7 +659,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
SymInfo = self.Trans.SymbolTable.get(class_name)
|
SymInfo = self.Trans.SymbolTable.lookup(class_name)
|
||||||
if SymInfo and SymInfo.Members:
|
if SymInfo and SymInfo.Members:
|
||||||
member_types = []
|
member_types = []
|
||||||
if isinstance(SymInfo.Members, dict):
|
if isinstance(SymInfo.Members, dict):
|
||||||
@@ -719,7 +718,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
if ClassName not in Gen.structs:
|
if ClassName not in Gen.structs:
|
||||||
self._ensure_struct_declared(ClassName)
|
self._ensure_struct_declared(ClassName)
|
||||||
SymKey = f'{ClassName}.{MethodName}'
|
SymKey = f'{ClassName}.{MethodName}'
|
||||||
SymInfo = self.Trans.SymbolTable.get(SymKey) or self.Trans.SymbolTable.get(MethodName)
|
SymInfo = self.Trans.SymbolTable.lookup(SymKey) or self.Trans.SymbolTable.lookup(MethodName)
|
||||||
if SymInfo and SymInfo.IsFunction:
|
if SymInfo and SymInfo.IsFunction:
|
||||||
ret_type_info = SymInfo.FuncPtrReturn
|
ret_type_info = SymInfo.FuncPtrReturn
|
||||||
if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
|
if isinstance(ret_type_info, CTypeInfo) and ret_type_info.BaseType:
|
||||||
@@ -761,7 +760,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return None
|
return None
|
||||||
CallArgs = []
|
CallArgs = []
|
||||||
SymKey = f'{ClassName}.{MethodName}'
|
SymKey = f'{ClassName}.{MethodName}'
|
||||||
SymInfo = self.Trans.SymbolTable.get(SymKey) or self.Trans.SymbolTable.get(MethodName)
|
SymInfo = self.Trans.SymbolTable.lookup(SymKey) or self.Trans.SymbolTable.lookup(MethodName)
|
||||||
is_static_call = SymInfo is not None and FuncMeta.STATIC_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
|
is_classmethod_call = SymInfo is not None and FuncMeta.CLASS_METHOD in SymInfo.MetaList
|
||||||
# @classmethod: 在参数列表前插入 cls(栈上分配的类实例指针)
|
# @classmethod: 在参数列表前插入 cls(栈上分配的类实例指针)
|
||||||
@@ -1208,14 +1207,12 @@ class ExprCallHandle(BaseHandle):
|
|||||||
|
|
||||||
# 解析 import 别名: 如 window -> vpsdk.window
|
# 解析 import 别名: 如 window -> vpsdk.window
|
||||||
if ModulePath and ModulePath not in ('c', 't'):
|
if ModulePath and ModulePath not in ('c', 't'):
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
ModulePath = self.Trans.SymbolTable.resolve_alias(ModulePath)
|
||||||
if ModulePath in import_aliases:
|
|
||||||
ModulePath = import_aliases[ModulePath]
|
|
||||||
|
|
||||||
is_user_module = (ModulePath and ModulePath not in ('c', 't') and
|
is_user_module = (ModulePath and ModulePath not in ('c', 't') and
|
||||||
(ModulePath in Gen.ModuleSha1Map or
|
(ModulePath in Gen.ModuleSha1Map or
|
||||||
ModulePath in getattr(self.Trans, '_ImportedModules', set()) or
|
ModulePath in getattr(self.Trans, '_ImportedModules', set()) or
|
||||||
ModulePath in getattr(self.Trans, '_ImportAliases', {})))
|
ModulePath in self.Trans.SymbolTable.import_aliases))
|
||||||
if ModulePath and ModulePath not in ('c', 't') and not is_user_module:
|
if ModulePath and ModulePath not in ('c', 't') and not is_user_module:
|
||||||
is_user_module = (ModulePath in Gen.ModuleSha1Map or
|
is_user_module = (ModulePath in Gen.ModuleSha1Map or
|
||||||
ModulePath.split('.')[-1] in Gen.ModuleSha1Map or
|
ModulePath.split('.')[-1] in Gen.ModuleSha1Map or
|
||||||
@@ -1229,12 +1226,12 @@ class ExprCallHandle(BaseHandle):
|
|||||||
if is_user_module:
|
if is_user_module:
|
||||||
mangled_name = Gen._mangle_func_name(func_name, ModulePath)
|
mangled_name = Gen._mangle_func_name(func_name, ModulePath)
|
||||||
sym_key = f'{ModulePath}.{func_name}'
|
sym_key = f'{ModulePath}.{func_name}'
|
||||||
sym_info = self.Trans.SymbolTable.get(sym_key) or self.Trans.SymbolTable.get(func_name)
|
sym_info = self.Trans.SymbolTable.lookup(sym_key) or self.Trans.SymbolTable.lookup(func_name)
|
||||||
is_inline = sym_info and (sym_info.IsInline or isinstance(sym_info.Storage, t.CInline))
|
is_inline = sym_info and (sym_info.IsInline or isinstance(sym_info.Storage, t.CInline))
|
||||||
if is_inline and sym_info.InlineBody:
|
if is_inline and sym_info.InlineBody:
|
||||||
self._HandleInlineExpandLlvm(Node, sym_info)
|
self._HandleInlineExpandLlvm(Node, sym_info)
|
||||||
return ir.Constant(ir.IntType(32), 1)
|
return ir.Constant(ir.IntType(32), 1)
|
||||||
sym_info_exact = self.Trans.SymbolTable.get(sym_key)
|
sym_info_exact = self.Trans.SymbolTable.lookup(sym_key)
|
||||||
if sym_info_exact:
|
if sym_info_exact:
|
||||||
exact_params = sym_info_exact.FuncPtrParams
|
exact_params = sym_info_exact.FuncPtrParams
|
||||||
exact_param_names = [pn for pn, _ in exact_params]
|
exact_param_names = [pn for pn, _ in exact_params]
|
||||||
@@ -1276,9 +1273,9 @@ class ExprCallHandle(BaseHandle):
|
|||||||
Gen.functions[func_name] = func_decl
|
Gen.functions[func_name] = func_decl
|
||||||
return self._HandleClosureCallLlvm(Node, decl_name)
|
return self._HandleClosureCallLlvm(Node, decl_name)
|
||||||
sym_key = f'{ModulePath}.{func_name}'
|
sym_key = f'{ModulePath}.{func_name}'
|
||||||
sym_info = self.Trans.SymbolTable.get(sym_key)
|
sym_info = self.Trans.SymbolTable.lookup(sym_key)
|
||||||
if not sym_info:
|
if not sym_info:
|
||||||
sym_info = self.Trans.SymbolTable.get(func_name)
|
sym_info = self.Trans.SymbolTable.lookup(func_name)
|
||||||
if sym_info:
|
if sym_info:
|
||||||
is_func = sym_info.IsFunction
|
is_func = sym_info.IsFunction
|
||||||
sym_is_variadic = sym_info.IsVariadic
|
sym_is_variadic = sym_info.IsVariadic
|
||||||
@@ -1407,9 +1404,9 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return self._HandleClosureCallLlvm(Node, decl_name)
|
return self._HandleClosureCallLlvm(Node, decl_name)
|
||||||
|
|
||||||
sym_key = f'{ModulePath}.{func_name}' if ModulePath else func_name
|
sym_key = f'{ModulePath}.{func_name}' if ModulePath else func_name
|
||||||
sym_info = self.Trans.SymbolTable.get(sym_key)
|
sym_info = self.Trans.SymbolTable.lookup(sym_key)
|
||||||
if not sym_info:
|
if not sym_info:
|
||||||
sym_info = self.Trans.SymbolTable.get(func_name)
|
sym_info = self.Trans.SymbolTable.lookup(func_name)
|
||||||
if sym_info:
|
if sym_info:
|
||||||
is_func = sym_info.IsFunction
|
is_func = sym_info.IsFunction
|
||||||
sym_is_variadic = sym_info.IsVariadic
|
sym_is_variadic = sym_info.IsVariadic
|
||||||
@@ -1576,7 +1573,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
|
|
||||||
def _HandleTypedefCastLlvm(self, Node, TypedefName):
|
def _HandleTypedefCastLlvm(self, Node, TypedefName):
|
||||||
Gen = self.Trans.LlvmGen
|
Gen = self.Trans.LlvmGen
|
||||||
SymInfo = self.Trans.SymbolTable.get(TypedefName)
|
SymInfo = self.Trans.SymbolTable.lookup(TypedefName)
|
||||||
if not SymInfo or not SymInfo.IsTypedef:
|
if not SymInfo or not SymInfo.IsTypedef:
|
||||||
return ir.Constant(ir.IntType(32), 0)
|
return ir.Constant(ir.IntType(32), 0)
|
||||||
TargetType = Gen._ctype_to_llvm(SymInfo)
|
TargetType = Gen._ctype_to_llvm(SymInfo)
|
||||||
@@ -1829,7 +1826,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
ClassName = Gen.var_struct_class.get(VarName)
|
ClassName = Gen.var_struct_class.get(VarName)
|
||||||
if ClassName:
|
if ClassName:
|
||||||
SymKey = f'{ClassName}.{MethodName}'
|
SymKey = f'{ClassName}.{MethodName}'
|
||||||
SymInfo = self.Trans.SymbolTable.get(SymKey)
|
SymInfo = self.Trans.SymbolTable.lookup(SymKey)
|
||||||
if SymInfo and SymInfo.MetaList:
|
if SymInfo and SymInfo.MetaList:
|
||||||
if FuncMeta.STATIC_METHOD in SymInfo.MetaList:
|
if FuncMeta.STATIC_METHOD in SymInfo.MetaList:
|
||||||
return self._HandleStaticMethodCallLlvm(Node, ClassName, MethodName)
|
return self._HandleStaticMethodCallLlvm(Node, ClassName, MethodName)
|
||||||
@@ -1901,7 +1898,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
if is_float:
|
if is_float:
|
||||||
return ir.Constant(ir.FloatType() if target_bits == 32 else ir.DoubleType(), 0.0)
|
return ir.Constant(ir.FloatType() if target_bits == 32 else ir.DoubleType(), 0.0)
|
||||||
return ir.Constant(ir.IntType(target_bits) if target_bits > 0 else ir.IntType(32), 0)
|
return ir.Constant(ir.IntType(target_bits) if target_bits > 0 else ir.IntType(32), 0)
|
||||||
if MethodName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(MethodName):
|
||||||
SymInfo = self.Trans.SymbolTable[MethodName]
|
SymInfo = self.Trans.SymbolTable[MethodName]
|
||||||
if SymInfo.IsTypedef:
|
if SymInfo.IsTypedef:
|
||||||
return self._HandleTypedefCastLlvm(Node, MethodName)
|
return self._HandleTypedefCastLlvm(Node, MethodName)
|
||||||
@@ -1982,9 +1979,8 @@ class ExprCallHandle(BaseHandle):
|
|||||||
ObjVal = tmp
|
ObjVal = tmp
|
||||||
if isinstance(Node.func.value, ast.Name):
|
if isinstance(Node.func.value, ast.Name):
|
||||||
ModuleName = Node.func.value.id
|
ModuleName = Node.func.value.id
|
||||||
aliases = getattr(self.Trans, '_ImportAliases', {})
|
|
||||||
imported = getattr(self.Trans, '_ImportedModules', set())
|
imported = getattr(self.Trans, '_ImportedModules', set())
|
||||||
actual_module = aliases.get(ModuleName, ModuleName)
|
actual_module = self.Trans.SymbolTable.resolve_alias(ModuleName)
|
||||||
if ModuleName in imported or actual_module in imported:
|
if ModuleName in imported or actual_module in imported:
|
||||||
mangled_name = Gen._mangle_func_name(MethodName, actual_module)
|
mangled_name = Gen._mangle_func_name(MethodName, actual_module)
|
||||||
if Gen._has_function(mangled_name):
|
if Gen._has_function(mangled_name):
|
||||||
@@ -2657,7 +2653,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
type_info = Gen.var_type_info[arg_name]
|
type_info = Gen.var_type_info[arg_name]
|
||||||
if isinstance(type_info, dict) and type_info.get('type') == 'enum':
|
if isinstance(type_info, dict) and type_info.get('type') == 'enum':
|
||||||
enum_type_name = type_info.get('name')
|
enum_type_name = type_info.get('name')
|
||||||
if not enum_type_name and arg_name in self.Trans.SymbolTable:
|
if not enum_type_name and self.Trans.SymbolTable.has(arg_name):
|
||||||
TypeInfo = self.Trans.SymbolTable[arg_name]
|
TypeInfo = self.Trans.SymbolTable[arg_name]
|
||||||
if TypeInfo.IsEnum:
|
if TypeInfo.IsEnum:
|
||||||
enum_type_name = arg_name
|
enum_type_name = arg_name
|
||||||
@@ -2666,7 +2662,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
enum_class_name = None
|
enum_class_name = None
|
||||||
if isinstance(arg.value, ast.Name):
|
if isinstance(arg.value, ast.Name):
|
||||||
LastPart = arg.attr
|
LastPart = arg.attr
|
||||||
if LastPart in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(LastPart):
|
||||||
AttrInfo = self.Trans.SymbolTable[LastPart]
|
AttrInfo = self.Trans.SymbolTable[LastPart]
|
||||||
if AttrInfo.IsEnumMember and AttrInfo.EnumName:
|
if AttrInfo.IsEnumMember and AttrInfo.EnumName:
|
||||||
enum_type_name = AttrInfo.EnumName
|
enum_type_name = AttrInfo.EnumName
|
||||||
@@ -2681,7 +2677,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
qualified_name_under = f"{enum_class_name}_{LastPart}"
|
qualified_name_under = f"{enum_class_name}_{LastPart}"
|
||||||
enum_member_found = None
|
enum_member_found = None
|
||||||
for qname in (qualified_name_dot, qualified_name_under):
|
for qname in (qualified_name_dot, qualified_name_under):
|
||||||
if qname in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(qname):
|
||||||
info = self.Trans.SymbolTable[qname]
|
info = self.Trans.SymbolTable[qname]
|
||||||
if info.IsEnumMember and info.EnumName == enum_class_name:
|
if info.IsEnumMember and info.EnumName == enum_class_name:
|
||||||
enum_member_found = info
|
enum_member_found = info
|
||||||
@@ -3425,7 +3421,7 @@ class ExprCallHandle(BaseHandle):
|
|||||||
type_str = 'int'
|
type_str = 'int'
|
||||||
type_name = attr_name
|
type_name = attr_name
|
||||||
elif isinstance(arg_node, ast.Name):
|
elif isinstance(arg_node, ast.Name):
|
||||||
var_info = self.Trans.SymbolTable.get(arg_node.id)
|
var_info = self.Trans.SymbolTable.lookup(arg_node.id)
|
||||||
if var_info and isinstance(var_info, dict):
|
if var_info and isinstance(var_info, dict):
|
||||||
var_type = var_info.get('type', '')
|
var_type = var_info.get('type', '')
|
||||||
if var_type in ('double', 'float'):
|
if var_type in ('double', 'float'):
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class ExprUtils:
|
|||||||
return ir.IntType(32)
|
return ir.IntType(32)
|
||||||
elif isinstance(node, ast.Attribute):
|
elif isinstance(node, ast.Attribute):
|
||||||
attr_name = node.attr
|
attr_name = node.attr
|
||||||
if attr_name in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(attr_name):
|
||||||
AttrInfo = self.Trans.SymbolTable[attr_name]
|
AttrInfo = self.Trans.SymbolTable[attr_name]
|
||||||
if getattr(AttrInfo, 'IsEnumMember', None):
|
if getattr(AttrInfo, 'IsEnumMember', None):
|
||||||
return ir.IntType(32)
|
return ir.IntType(32)
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ class FunctionHandle(BaseHandle):
|
|||||||
elif isinstance(val.func, ast.Attribute):
|
elif isinstance(val.func, ast.Attribute):
|
||||||
callee_name = getattr(val.func, 'attr', None)
|
callee_name = getattr(val.func, 'attr', None)
|
||||||
if callee_name:
|
if callee_name:
|
||||||
sym = self.Trans.SymbolTable.get(callee_name)
|
sym = self.Trans.SymbolTable.lookup(callee_name)
|
||||||
if sym and isinstance(sym, dict):
|
if sym and isinstance(sym, dict):
|
||||||
ret_type_str = sym.get('return_type', '')
|
ret_type_str = sym.get('return_type', '')
|
||||||
if ret_type_str and ret_type_str != 'int':
|
if ret_type_str and ret_type_str != 'int':
|
||||||
@@ -203,7 +203,7 @@ class FunctionHandle(BaseHandle):
|
|||||||
var_name = val.id
|
var_name = val.id
|
||||||
if var_name in local_var_types:
|
if var_name in local_var_types:
|
||||||
return local_var_types[var_name]
|
return local_var_types[var_name]
|
||||||
var_info = self.Trans.SymbolTable.get(var_name)
|
var_info = self.Trans.SymbolTable.lookup(var_name)
|
||||||
if var_info and isinstance(var_info, dict):
|
if var_info and isinstance(var_info, dict):
|
||||||
var_type = var_info.get('type', '')
|
var_type = var_info.get('type', '')
|
||||||
if var_type and var_type != 'int':
|
if var_type and var_type != 'int':
|
||||||
@@ -259,7 +259,7 @@ class FunctionHandle(BaseHandle):
|
|||||||
break
|
break
|
||||||
if isinstance(val.value, ast.Name):
|
if isinstance(val.value, ast.Name):
|
||||||
var_name = val.value.id
|
var_name = val.value.id
|
||||||
var_info = self.Trans.SymbolTable.get(var_name)
|
var_info = self.Trans.SymbolTable.lookup(var_name)
|
||||||
if var_info and isinstance(var_info, dict):
|
if var_info and isinstance(var_info, dict):
|
||||||
var_type = var_info.get('type', '')
|
var_type = var_info.get('type', '')
|
||||||
if var_type.startswith('list[') or var_type.startswith('List['):
|
if var_type.startswith('list[') or var_type.startswith('List['):
|
||||||
@@ -1386,7 +1386,7 @@ class FunctionHandle(BaseHandle):
|
|||||||
if self.Trans.VarScopes:
|
if self.Trans.VarScopes:
|
||||||
self.Trans.VarScopes.pop()
|
self.Trans.VarScopes.pop()
|
||||||
self.Trans.FunctionReturnTypes[FuncName] = ReturnTypeInfo
|
self.Trans.FunctionReturnTypes[FuncName] = ReturnTypeInfo
|
||||||
if FuncName not in self.Trans.SymbolTable:
|
if not self.Trans.SymbolTable.has(FuncName):
|
||||||
FuncInfo = CTypeInfo()
|
FuncInfo = CTypeInfo()
|
||||||
FuncInfo.Name = FuncName
|
FuncInfo.Name = FuncName
|
||||||
FuncInfo.IsFunction = True
|
FuncInfo.IsFunction = True
|
||||||
@@ -1395,7 +1395,7 @@ class FunctionHandle(BaseHandle):
|
|||||||
FuncInfo.IsInline = True
|
FuncInfo.IsInline = True
|
||||||
FuncInfo.InlineBody = Node.body
|
FuncInfo.InlineBody = Node.body
|
||||||
FuncInfo.InlineParams = [arg.arg for arg in Node.args.args]
|
FuncInfo.InlineParams = [arg.arg for arg in Node.args.args]
|
||||||
self.Trans.SymbolTable[FuncName] = FuncInfo
|
self.Trans.SymbolTable.insert(FuncName, FuncInfo)
|
||||||
else:
|
else:
|
||||||
existing = self.Trans.SymbolTable[FuncName]
|
existing = self.Trans.SymbolTable[FuncName]
|
||||||
if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
|
if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
|
||||||
@@ -1407,7 +1407,7 @@ class FunctionHandle(BaseHandle):
|
|||||||
# property setter/deleter: 在原始 PropKey(不带后缀)下注册 MetaList
|
# property setter/deleter: 在原始 PropKey(不带后缀)下注册 MetaList
|
||||||
if FuncMeta.PROPERTY_SETTER in func_meta or FuncMeta.PROPERTY_DELETER in func_meta:
|
if FuncMeta.PROPERTY_SETTER in func_meta or FuncMeta.PROPERTY_DELETER in func_meta:
|
||||||
BasePropKey = f"{ClassName}.{RawFuncName}" if ClassName else RawFuncName
|
BasePropKey = f"{ClassName}.{RawFuncName}" if ClassName else RawFuncName
|
||||||
if BasePropKey in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(BasePropKey):
|
||||||
base_existing = self.Trans.SymbolTable[BasePropKey]
|
base_existing = self.Trans.SymbolTable[BasePropKey]
|
||||||
if func_meta != FuncMeta.NONE:
|
if func_meta != FuncMeta.NONE:
|
||||||
base_existing.MetaList = base_existing.MetaList | func_meta
|
base_existing.MetaList = base_existing.MetaList | func_meta
|
||||||
@@ -1416,5 +1416,5 @@ class FunctionHandle(BaseHandle):
|
|||||||
PropInfo.Name = BasePropKey
|
PropInfo.Name = BasePropKey
|
||||||
PropInfo.IsFunction = True
|
PropInfo.IsFunction = True
|
||||||
PropInfo.MetaList = func_meta
|
PropInfo.MetaList = func_meta
|
||||||
self.Trans.SymbolTable[BasePropKey] = PropInfo
|
self.Trans.SymbolTable.insert(BasePropKey, PropInfo)
|
||||||
return func
|
return func
|
||||||
|
|||||||
@@ -71,10 +71,8 @@ class IfHandle(BaseHandle):
|
|||||||
Gen = self.Trans.LlvmGen
|
Gen = self.Trans.LlvmGen
|
||||||
if hasattr(Gen, '_define_constants') and name in Gen._define_constants:
|
if hasattr(Gen, '_define_constants') and name in Gen._define_constants:
|
||||||
return True
|
return True
|
||||||
if name in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.is_define(name):
|
||||||
info = self.Trans.SymbolTable[name]
|
return True
|
||||||
if info.IsDefine:
|
|
||||||
return True
|
|
||||||
platform_macros = self._get_platform_macros()
|
platform_macros = self._get_platform_macros()
|
||||||
return name in platform_macros
|
return name in platform_macros
|
||||||
|
|
||||||
@@ -84,7 +82,7 @@ class IfHandle(BaseHandle):
|
|||||||
val = Gen._define_constants[name]
|
val = Gen._define_constants[name]
|
||||||
if isinstance(val, (int, float)):
|
if isinstance(val, (int, float)):
|
||||||
return val
|
return val
|
||||||
if name in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(name):
|
||||||
info = self.Trans.SymbolTable[name]
|
info = self.Trans.SymbolTable[name]
|
||||||
if info.IsDefine:
|
if info.IsDefine:
|
||||||
val = info.DefineValue
|
val = info.DefineValue
|
||||||
|
|||||||
@@ -45,20 +45,18 @@ class ImportHandle(BaseHandle):
|
|||||||
def _EmitImportDeclarationsLlvm(self, Node, Gen):
|
def _EmitImportDeclarationsLlvm(self, Node, Gen):
|
||||||
if not getattr(self.Trans, '_ImportedModules', None):
|
if not getattr(self.Trans, '_ImportedModules', None):
|
||||||
self.Trans._ImportedModules = set()
|
self.Trans._ImportedModules = set()
|
||||||
if not getattr(self.Trans, '_ImportAliases', None):
|
|
||||||
self.Trans._ImportAliases = {}
|
|
||||||
for alias in Node.names:
|
for alias in Node.names:
|
||||||
name = alias.name
|
name = alias.name
|
||||||
if name in ('c', 't'):
|
if name in ('c', 't'):
|
||||||
continue
|
continue
|
||||||
self.Trans._ImportedModules.add(name)
|
self.Trans._ImportedModules.add(name)
|
||||||
if alias.asname:
|
if alias.asname:
|
||||||
self.Trans._ImportAliases[alias.asname] = name
|
self.Trans.SymbolTable.import_aliases[alias.asname] = name
|
||||||
# 同时在符号表中注册模块别名,以便 CTypeInfo.FromNode 能解析
|
# 同时在符号表中注册模块别名,以便 CTypeInfo.FromNode 能解析
|
||||||
AliasInfo = CTypeInfo()
|
AliasInfo = CTypeInfo()
|
||||||
AliasInfo.IsModuleAlias = True
|
AliasInfo.IsModuleAlias = True
|
||||||
AliasInfo.ResolvedModule = name
|
AliasInfo.ResolvedModule = name
|
||||||
self.Trans.SymbolTable[alias.asname] = AliasInfo
|
self.Trans.SymbolTable.insert(alias.asname, AliasInfo)
|
||||||
current_module = self._get_current_module_name()
|
current_module = self._get_current_module_name()
|
||||||
self._EmitModuleDeclarationsLlvm(name, Gen, register_module_name=current_module)
|
self._EmitModuleDeclarationsLlvm(name, Gen, register_module_name=current_module)
|
||||||
|
|
||||||
@@ -73,14 +71,14 @@ class ImportHandle(BaseHandle):
|
|||||||
# into _define_constants so they can be found by _HandleNameLlvm
|
# into _define_constants so they can be found by _HandleNameLlvm
|
||||||
if not asname or asname == name:
|
if not asname or asname == name:
|
||||||
# Check if this name is a CDefine constant in SymbolTable
|
# Check if this name is a CDefine constant in SymbolTable
|
||||||
sym_info = self.Trans.SymbolTable.get(name)
|
sym_info = self.Trans.SymbolTable.lookup(name)
|
||||||
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
|
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
|
||||||
define_constants = vars(Gen).setdefault('_define_constants', {})
|
define_constants = vars(Gen).setdefault('_define_constants', {})
|
||||||
if name not in define_constants:
|
if name not in define_constants:
|
||||||
define_constants[name] = sym_info.DefineValue
|
define_constants[name] = sym_info.DefineValue
|
||||||
# Also check with module prefix
|
# Also check with module prefix
|
||||||
for prefix_key in [f"{module}.{name}", name]:
|
for prefix_key in [f"{module}.{name}", name]:
|
||||||
sym_info2 = self.Trans.SymbolTable.get(prefix_key)
|
sym_info2 = self.Trans.SymbolTable.lookup(prefix_key)
|
||||||
if sym_info2 and sym_info2.IsDefine and sym_info2.DefineValue is not None:
|
if sym_info2 and sym_info2.IsDefine and sym_info2.DefineValue is not None:
|
||||||
define_constants = vars(Gen).setdefault('_define_constants', {})
|
define_constants = vars(Gen).setdefault('_define_constants', {})
|
||||||
if name not in define_constants:
|
if name not in define_constants:
|
||||||
@@ -94,8 +92,8 @@ class ImportHandle(BaseHandle):
|
|||||||
Gen.functions[asname] = Gen.functions[name]
|
Gen.functions[asname] = Gen.functions[name]
|
||||||
if name in Gen.structs:
|
if name in Gen.structs:
|
||||||
Gen.structs[asname] = Gen.structs[name]
|
Gen.structs[asname] = Gen.structs[name]
|
||||||
if name in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(name):
|
||||||
self.Trans.SymbolTable[asname] = self.Trans.SymbolTable[name]
|
self.Trans.SymbolTable.insert(asname, self.Trans.SymbolTable[name])
|
||||||
if name in Gen.variables:
|
if name in Gen.variables:
|
||||||
Gen.variables[asname] = Gen.variables[name]
|
Gen.variables[asname] = Gen.variables[name]
|
||||||
if name in Gen.global_vars:
|
if name in Gen.global_vars:
|
||||||
@@ -107,7 +105,7 @@ class ImportHandle(BaseHandle):
|
|||||||
for key in list(self.Trans.SymbolTable.keys()):
|
for key in list(self.Trans.SymbolTable.keys()):
|
||||||
if key.startswith(f'{name}.'):
|
if key.startswith(f'{name}.'):
|
||||||
suffix = key[len(name):]
|
suffix = key[len(name):]
|
||||||
self.Trans.SymbolTable[f'{asname}{suffix}'] = self.Trans.SymbolTable[key]
|
self.Trans.SymbolTable.insert(f'{asname}{suffix}', self.Trans.SymbolTable[key])
|
||||||
for meta_dict in (Gen.class_members, Gen.class_member_defaults,
|
for meta_dict in (Gen.class_members, Gen.class_member_defaults,
|
||||||
Gen.class_member_signeds, Gen.class_member_bitfields,
|
Gen.class_member_signeds, Gen.class_member_bitfields,
|
||||||
Gen.class_member_byteorders, Gen.class_member_bitoffsets,
|
Gen.class_member_byteorders, Gen.class_member_bitoffsets,
|
||||||
@@ -127,8 +125,6 @@ class ImportHandle(BaseHandle):
|
|||||||
if module in ('c', 't'):
|
if module in ('c', 't'):
|
||||||
if not getattr(self.Trans, '_ImportedModules', None):
|
if not getattr(self.Trans, '_ImportedModules', None):
|
||||||
self.Trans._ImportedModules = set()
|
self.Trans._ImportedModules = set()
|
||||||
if not getattr(self.Trans, '_ImportAliases', None):
|
|
||||||
self.Trans._ImportAliases = {}
|
|
||||||
self.Trans._ImportedModules.add(module)
|
self.Trans._ImportedModules.add(module)
|
||||||
if not hasattr(self.Trans, '_t_c_imported_names'):
|
if not hasattr(self.Trans, '_t_c_imported_names'):
|
||||||
self.Trans._t_c_imported_names = {}
|
self.Trans._t_c_imported_names = {}
|
||||||
@@ -139,8 +135,6 @@ class ImportHandle(BaseHandle):
|
|||||||
return
|
return
|
||||||
if not getattr(self.Trans, '_ImportedModules', None):
|
if not getattr(self.Trans, '_ImportedModules', None):
|
||||||
self.Trans._ImportedModules = set()
|
self.Trans._ImportedModules = set()
|
||||||
if not getattr(self.Trans, '_ImportAliases', None):
|
|
||||||
self.Trans._ImportAliases = {}
|
|
||||||
current_module = self._get_current_module_name()
|
current_module = self._get_current_module_name()
|
||||||
if Node.level and Node.level > 0:
|
if Node.level and Node.level > 0:
|
||||||
current_file = getattr(self.Trans, 'CurrentFile', '') or ''
|
current_file = getattr(self.Trans, 'CurrentFile', '') or ''
|
||||||
@@ -190,7 +184,7 @@ class ImportHandle(BaseHandle):
|
|||||||
self.Trans._ImportedModules.add(alias.name)
|
self.Trans._ImportedModules.add(alias.name)
|
||||||
self._LoadModuleDeclarationsFromFile(sub_path, Gen, module_name=alias.name, register_module_name=current_module)
|
self._LoadModuleDeclarationsFromFile(sub_path, Gen, module_name=alias.name, register_module_name=current_module)
|
||||||
if alias.asname:
|
if alias.asname:
|
||||||
self.Trans._ImportAliases[alias.asname] = alias.name
|
self.Trans.SymbolTable.import_aliases[alias.asname] = alias.name
|
||||||
found_sub = True
|
found_sub = True
|
||||||
break
|
break
|
||||||
if not found_sub:
|
if not found_sub:
|
||||||
@@ -206,7 +200,7 @@ class ImportHandle(BaseHandle):
|
|||||||
self.Trans._ImportedModules.add(sub_ModulePath)
|
self.Trans._ImportedModules.add(sub_ModulePath)
|
||||||
self._LoadModuleDeclarationsFromFile(sha1_pyi, Gen, module_name=alias.name, register_module_name=current_module)
|
self._LoadModuleDeclarationsFromFile(sha1_pyi, Gen, module_name=alias.name, register_module_name=current_module)
|
||||||
if alias.asname:
|
if alias.asname:
|
||||||
self.Trans._ImportAliases[alias.asname] = alias.name
|
self.Trans.SymbolTable.import_aliases[alias.asname] = alias.name
|
||||||
self._RegisterFromImportAliases(Node, Gen, module or pkg_name)
|
self._RegisterFromImportAliases(Node, Gen, module or pkg_name)
|
||||||
return
|
return
|
||||||
self.Trans._ImportedModules.add(module)
|
self.Trans._ImportedModules.add(module)
|
||||||
@@ -725,19 +719,19 @@ class ImportHandle(BaseHandle):
|
|||||||
if isinstance(ValueTypeInfo, CTypeInfo) and (ValueTypeInfo.BaseType or ValueTypeInfo.PtrCount > 0):
|
if isinstance(ValueTypeInfo, CTypeInfo) and (ValueTypeInfo.BaseType or ValueTypeInfo.PtrCount > 0):
|
||||||
ValueTypeInfo.IsTypedef = True
|
ValueTypeInfo.IsTypedef = True
|
||||||
ValueTypeInfo.Name = VarName
|
ValueTypeInfo.Name = VarName
|
||||||
self.Trans.SymbolTable[VarName] = ValueTypeInfo
|
self.Trans.SymbolTable.insert(VarName, ValueTypeInfo)
|
||||||
if module_name:
|
if module_name:
|
||||||
FullName = f"{module_name}.{VarName}"
|
FullName = f"{module_name}.{VarName}"
|
||||||
self.Trans.SymbolTable[FullName] = ValueTypeInfo
|
self.Trans.SymbolTable.insert(FullName, ValueTypeInfo)
|
||||||
return
|
return
|
||||||
TTypeInfo = self.Trans.TypeMergeHandler.GetCTypeInfo(Node.annotation)
|
TTypeInfo = self.Trans.TypeMergeHandler.GetCTypeInfo(Node.annotation)
|
||||||
if TTypeInfo:
|
if TTypeInfo:
|
||||||
TTypeInfo.IsTypedef = True
|
TTypeInfo.IsTypedef = True
|
||||||
TTypeInfo.Name = VarName
|
TTypeInfo.Name = VarName
|
||||||
self.Trans.SymbolTable[VarName] = TTypeInfo
|
self.Trans.SymbolTable.insert(VarName, TTypeInfo)
|
||||||
if module_name:
|
if module_name:
|
||||||
FullName = f"{module_name}.{VarName}"
|
FullName = f"{module_name}.{VarName}"
|
||||||
self.Trans.SymbolTable[FullName] = TTypeInfo
|
self.Trans.SymbolTable.insert(FullName, TTypeInfo)
|
||||||
return
|
return
|
||||||
|
|
||||||
if IsCDefine:
|
if IsCDefine:
|
||||||
@@ -948,7 +942,7 @@ class ImportHandle(BaseHandle):
|
|||||||
info.Lineno = lineno
|
info.Lineno = lineno
|
||||||
info.file = FilePath
|
info.file = FilePath
|
||||||
# 直接添加到 SymbolTable 字典
|
# 直接添加到 SymbolTable 字典
|
||||||
self.Trans.SymbolTable[FullName] = info
|
self.Trans.SymbolTable.insert(FullName, info)
|
||||||
|
|
||||||
def _check_annotation_for_state(self, annotation) -> bool:
|
def _check_annotation_for_state(self, annotation) -> bool:
|
||||||
import ast
|
import ast
|
||||||
@@ -1020,7 +1014,7 @@ class ImportHandle(BaseHandle):
|
|||||||
ParamTypes = []
|
ParamTypes = []
|
||||||
is_method = is_class_method or '.__' in FuncName
|
is_method = is_class_method or '.__' in FuncName
|
||||||
class_name_for_method = FuncName.split('.')[0] if '.' in FuncName else None
|
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 self.Trans.SymbolTable[class_name_for_method].IsCpythonObject
|
class_is_cpython = class_name_for_method and self.Trans.SymbolTable.is_struct(class_name_for_method)
|
||||||
for i, Arg in enumerate(Node.args.args):
|
for i, Arg in enumerate(Node.args.args):
|
||||||
if i == 0 and is_method:
|
if i == 0 and is_method:
|
||||||
# self parameter of a method should always be a pointer to the struct
|
# self parameter of a method should always be a pointer to the struct
|
||||||
@@ -1107,12 +1101,12 @@ class ImportHandle(BaseHandle):
|
|||||||
func_meta |= FuncMeta.PROPERTY_GETTER
|
func_meta |= FuncMeta.PROPERTY_GETTER
|
||||||
elif d.attr == 'deleter':
|
elif d.attr == 'deleter':
|
||||||
func_meta |= FuncMeta.PROPERTY_DELETER
|
func_meta |= FuncMeta.PROPERTY_DELETER
|
||||||
if FuncName not in self.Trans.SymbolTable:
|
if not self.Trans.SymbolTable.has(FuncName):
|
||||||
FuncInfo = CTypeInfo()
|
FuncInfo = CTypeInfo()
|
||||||
FuncInfo.Name = FuncName
|
FuncInfo.Name = FuncName
|
||||||
FuncInfo.IsFunction = True
|
FuncInfo.IsFunction = True
|
||||||
FuncInfo.MetaList = func_meta
|
FuncInfo.MetaList = func_meta
|
||||||
self.Trans.SymbolTable[FuncName] = FuncInfo
|
self.Trans.SymbolTable.insert(FuncName, FuncInfo)
|
||||||
else:
|
else:
|
||||||
existing = self.Trans.SymbolTable[FuncName]
|
existing = self.Trans.SymbolTable[FuncName]
|
||||||
if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
|
if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
|
||||||
@@ -1120,16 +1114,16 @@ class ImportHandle(BaseHandle):
|
|||||||
# 同时注册带模块前缀的符号,以便 module.func_name 查找能命中
|
# 同时注册带模块前缀的符号,以便 module.func_name 查找能命中
|
||||||
if source_module_name and source_module_name not in ('c', 't'):
|
if source_module_name and source_module_name not in ('c', 't'):
|
||||||
FullSymKey = f"{source_module_name}.{FuncName}"
|
FullSymKey = f"{source_module_name}.{FuncName}"
|
||||||
if FullSymKey not in self.Trans.SymbolTable:
|
if not self.Trans.SymbolTable.has(FullSymKey):
|
||||||
FullFuncInfo = CTypeInfo()
|
FullFuncInfo = CTypeInfo()
|
||||||
FullFuncInfo.Name = FullSymKey
|
FullFuncInfo.Name = FullSymKey
|
||||||
FullFuncInfo.IsFunction = True
|
FullFuncInfo.IsFunction = True
|
||||||
FullFuncInfo.MetaList = func_meta
|
FullFuncInfo.MetaList = func_meta
|
||||||
self.Trans.SymbolTable[FullSymKey] = FullFuncInfo
|
self.Trans.SymbolTable.insert(FullSymKey, FullFuncInfo)
|
||||||
# property setter/deleter: 在原始 PropKey(不带后缀)下注册 MetaList
|
# property setter/deleter: 在原始 PropKey(不带后缀)下注册 MetaList
|
||||||
if FuncMeta.PROPERTY_SETTER in func_meta or FuncMeta.PROPERTY_DELETER in func_meta:
|
if FuncMeta.PROPERTY_SETTER in func_meta or FuncMeta.PROPERTY_DELETER in func_meta:
|
||||||
BasePropKey = FuncName.replace('$set', '').replace('$del', '')
|
BasePropKey = FuncName.replace('$set', '').replace('$del', '')
|
||||||
if BasePropKey in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(BasePropKey):
|
||||||
base_existing = self.Trans.SymbolTable[BasePropKey]
|
base_existing = self.Trans.SymbolTable[BasePropKey]
|
||||||
if func_meta != FuncMeta.NONE:
|
if func_meta != FuncMeta.NONE:
|
||||||
base_existing.MetaList = base_existing.MetaList | func_meta
|
base_existing.MetaList = base_existing.MetaList | func_meta
|
||||||
@@ -1138,7 +1132,7 @@ class ImportHandle(BaseHandle):
|
|||||||
PropInfo.Name = BasePropKey
|
PropInfo.Name = BasePropKey
|
||||||
PropInfo.IsFunction = True
|
PropInfo.IsFunction = True
|
||||||
PropInfo.MetaList = func_meta
|
PropInfo.MetaList = func_meta
|
||||||
self.Trans.SymbolTable[BasePropKey] = PropInfo
|
self.Trans.SymbolTable.insert(BasePropKey, PropInfo)
|
||||||
if register_module_name and register_module_name != source_module_name:
|
if register_module_name and register_module_name != source_module_name:
|
||||||
ReexportName = Gen._mangle_func_name(FuncName, module_name=register_module_name)
|
ReexportName = Gen._mangle_func_name(FuncName, module_name=register_module_name)
|
||||||
Gen.functions[ReexportName] = func
|
Gen.functions[ReexportName] = func
|
||||||
@@ -1208,14 +1202,14 @@ class ImportHandle(BaseHandle):
|
|||||||
CInfo.IsStruct = True
|
CInfo.IsStruct = True
|
||||||
if module_name:
|
if module_name:
|
||||||
FullName = f"{module_name}.{ClassName}"
|
FullName = f"{module_name}.{ClassName}"
|
||||||
self.Trans.SymbolTable[FullName] = CInfo
|
self.Trans.SymbolTable.insert(FullName, CInfo)
|
||||||
self.Trans.SymbolTable[ClassName] = CInfo
|
self.Trans.SymbolTable.insert(ClassName, CInfo)
|
||||||
if IsCenum:
|
if IsCenum:
|
||||||
EnumTypeNode = CTypeInfo()
|
EnumTypeNode = CTypeInfo()
|
||||||
EnumTypeNode.Name = ClassName
|
EnumTypeNode.Name = ClassName
|
||||||
EnumTypeNode.BaseType = t.CEnum(ClassName)
|
EnumTypeNode.BaseType = t.CEnum(ClassName)
|
||||||
EnumTypeNode.IsEnum = True
|
EnumTypeNode.IsEnum = True
|
||||||
self.Trans.SymbolTable[ClassName] = EnumTypeNode
|
self.Trans.SymbolTable.insert(ClassName, EnumTypeNode)
|
||||||
for item in Node.body:
|
for item in Node.body:
|
||||||
VarName = None
|
VarName = None
|
||||||
if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
|
if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
|
||||||
@@ -1237,9 +1231,9 @@ class ImportHandle(BaseHandle):
|
|||||||
MemberNode.EnumName = ClassName
|
MemberNode.EnumName = ClassName
|
||||||
MemberNode.Lineno = item.lineno
|
MemberNode.Lineno = item.lineno
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.Trans.SymbolTable[VarName] = MemberNode
|
self.Trans.SymbolTable.insert(VarName, MemberNode)
|
||||||
self.Trans.SymbolTable[f"{ClassName}.{VarName}"] = MemberNode
|
self.Trans.SymbolTable.insert(f"{ClassName}.{VarName}", MemberNode)
|
||||||
self.Trans.SymbolTable[f"{ClassName}_{VarName}"] = MemberNode
|
self.Trans.SymbolTable.insert(f"{ClassName}_{VarName}", MemberNode)
|
||||||
return
|
return
|
||||||
self._TryLoadStructFromStub(ClassName, Gen)
|
self._TryLoadStructFromStub(ClassName, Gen)
|
||||||
source_sha1 = None
|
source_sha1 = None
|
||||||
@@ -1334,19 +1328,19 @@ class ImportHandle(BaseHandle):
|
|||||||
func_meta |= FuncMeta.PROPERTY_DELETER
|
func_meta |= FuncMeta.PROPERTY_DELETER
|
||||||
# setter/deleter 的 SymKey 使用带后缀的函数名
|
# setter/deleter 的 SymKey 使用带后缀的函数名
|
||||||
SymKey = DeclFuncName
|
SymKey = DeclFuncName
|
||||||
if SymKey not in self.Trans.SymbolTable:
|
if not self.Trans.SymbolTable.has(SymKey):
|
||||||
FuncInfo = CTypeInfo()
|
FuncInfo = CTypeInfo()
|
||||||
FuncInfo.Name = SymKey
|
FuncInfo.Name = SymKey
|
||||||
FuncInfo.IsFunction = True
|
FuncInfo.IsFunction = True
|
||||||
FuncInfo.MetaList = func_meta
|
FuncInfo.MetaList = func_meta
|
||||||
self.Trans.SymbolTable[SymKey] = FuncInfo
|
self.Trans.SymbolTable.insert(SymKey, FuncInfo)
|
||||||
else:
|
else:
|
||||||
existing = self.Trans.SymbolTable[SymKey]
|
existing = self.Trans.SymbolTable[SymKey]
|
||||||
if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
|
if existing.MetaList == FuncMeta.NONE and func_meta != FuncMeta.NONE:
|
||||||
existing.MetaList = func_meta
|
existing.MetaList = func_meta
|
||||||
# setter/deleter: 同时在原始 PropKey(不带后缀)下注册 MetaList
|
# setter/deleter: 同时在原始 PropKey(不带后缀)下注册 MetaList
|
||||||
if is_item_prop_setter or is_item_prop_deleter:
|
if is_item_prop_setter or is_item_prop_deleter:
|
||||||
if FuncFullName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FuncFullName):
|
||||||
base_existing = self.Trans.SymbolTable[FuncFullName]
|
base_existing = self.Trans.SymbolTable[FuncFullName]
|
||||||
if func_meta != FuncMeta.NONE:
|
if func_meta != FuncMeta.NONE:
|
||||||
base_existing.MetaList = base_existing.MetaList | func_meta
|
base_existing.MetaList = base_existing.MetaList | func_meta
|
||||||
@@ -1355,7 +1349,7 @@ class ImportHandle(BaseHandle):
|
|||||||
PropInfo.Name = FuncFullName
|
PropInfo.Name = FuncFullName
|
||||||
PropInfo.IsFunction = True
|
PropInfo.IsFunction = True
|
||||||
PropInfo.MetaList = func_meta
|
PropInfo.MetaList = func_meta
|
||||||
self.Trans.SymbolTable[FuncFullName] = PropInfo
|
self.Trans.SymbolTable.insert(FuncFullName, PropInfo)
|
||||||
if has_methods:
|
if has_methods:
|
||||||
if IsCVTable:
|
if IsCVTable:
|
||||||
Gen._cross_module_vtable_classes.add(ClassName)
|
Gen._cross_module_vtable_classes.add(ClassName)
|
||||||
|
|||||||
@@ -19,9 +19,8 @@ class MatchHandle(BaseHandle):
|
|||||||
SubjectPtr = None
|
SubjectPtr = None
|
||||||
if isinstance(Node.subject, ast.Name):
|
if isinstance(Node.subject, ast.Name):
|
||||||
VarName = Node.subject.id
|
VarName = Node.subject.id
|
||||||
if VarName in self.Trans.SymbolTable:
|
TypeInfo = self.Trans.SymbolTable.lookup(VarName)
|
||||||
TypeInfo = self.Trans.SymbolTable[VarName]
|
if TypeInfo and TypeInfo.IsRenum:
|
||||||
if TypeInfo.IsRenum:
|
|
||||||
IsRenumMatch = True
|
IsRenumMatch = True
|
||||||
RenumName = TypeInfo.Name
|
RenumName = TypeInfo.Name
|
||||||
SubjectPtr = Gen._loadVar(VarName)
|
SubjectPtr = Gen._loadVar(VarName)
|
||||||
@@ -35,11 +34,11 @@ class MatchHandle(BaseHandle):
|
|||||||
VariantName = cls_node.id
|
VariantName = cls_node.id
|
||||||
elif isinstance(cls_node, ast.Attribute):
|
elif isinstance(cls_node, ast.Attribute):
|
||||||
VariantName = cls_node.attr
|
VariantName = cls_node.attr
|
||||||
if VariantName and VariantName in self.Trans.SymbolTable:
|
if VariantName and self.Trans.SymbolTable.has(VariantName):
|
||||||
SymInfo = self.Trans.SymbolTable[VariantName]
|
SymInfo = self.Trans.SymbolTable[VariantName]
|
||||||
if SymInfo.IsEnumMember and SymInfo.EnumName:
|
if SymInfo.IsEnumMember and SymInfo.EnumName:
|
||||||
EnumName = SymInfo.EnumName
|
EnumName = SymInfo.EnumName
|
||||||
if EnumName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(EnumName):
|
||||||
EnumInfo = self.Trans.SymbolTable[EnumName]
|
EnumInfo = self.Trans.SymbolTable[EnumName]
|
||||||
if EnumInfo.IsRenum:
|
if EnumInfo.IsRenum:
|
||||||
IsRenumMatch = True
|
IsRenumMatch = True
|
||||||
@@ -207,7 +206,7 @@ class MatchHandle(BaseHandle):
|
|||||||
VariantName = cls_node.attr
|
VariantName = cls_node.attr
|
||||||
if VariantName:
|
if VariantName:
|
||||||
TagValue = None
|
TagValue = None
|
||||||
if VariantName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(VariantName):
|
||||||
SymInfo = self.Trans.SymbolTable[VariantName]
|
SymInfo = self.Trans.SymbolTable[VariantName]
|
||||||
if SymInfo.IsEnumMember:
|
if SymInfo.IsEnumMember:
|
||||||
TagValue = SymInfo.value
|
TagValue = SymInfo.value
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
)
|
)
|
||||||
ast.copy_location(virtual_attr, Node)
|
ast.copy_location(virtual_attr, Node)
|
||||||
return self.GetCTypeInfo(virtual_attr)
|
return self.GetCTypeInfo(virtual_attr)
|
||||||
if TypeName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(TypeName):
|
||||||
Entry = self.Trans.SymbolTable[TypeName]
|
Entry = self.Trans.SymbolTable[TypeName]
|
||||||
if Entry and Entry.IsTypedef:
|
if Entry and Entry.IsTypedef:
|
||||||
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
||||||
@@ -113,12 +113,12 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
|
|
||||||
# 解析 import 别名: 如 import fat32_types as types -> types -> fat32_types
|
# 解析 import 别名: 如 import fat32_types as types -> types -> fat32_types
|
||||||
if ModulePath:
|
if ModulePath:
|
||||||
import_aliases = getattr(self.Trans, '_ImportAliases', {})
|
import_aliases = self.Trans.SymbolTable.import_aliases
|
||||||
if ModulePath in import_aliases:
|
if ModulePath in import_aliases:
|
||||||
ModulePath = import_aliases[ModulePath]
|
ModulePath = import_aliases[ModulePath]
|
||||||
else:
|
else:
|
||||||
# 也尝试在符号表中查找模块别名
|
# 也尝试在符号表中查找模块别名
|
||||||
if ModulePath in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(ModulePath):
|
||||||
entry = self.Trans.SymbolTable[ModulePath]
|
entry = self.Trans.SymbolTable[ModulePath]
|
||||||
if isinstance(entry, CTypeInfo) and entry.IsModuleAlias:
|
if isinstance(entry, CTypeInfo) and entry.IsModuleAlias:
|
||||||
resolved = entry.ResolvedModule
|
resolved = entry.ResolvedModule
|
||||||
@@ -185,7 +185,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
|
|
||||||
FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName
|
FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName
|
||||||
|
|
||||||
if TypeName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(TypeName):
|
||||||
Entry = self.Trans.SymbolTable[TypeName]
|
Entry = self.Trans.SymbolTable[TypeName]
|
||||||
if Entry and Entry.IsTypedef:
|
if Entry and Entry.IsTypedef:
|
||||||
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
||||||
@@ -213,7 +213,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
return Result
|
return Result
|
||||||
return CTypeInfo()
|
return CTypeInfo()
|
||||||
|
|
||||||
if FullName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FullName):
|
||||||
Info = self.Trans.SymbolTable[FullName]
|
Info = self.Trans.SymbolTable[FullName]
|
||||||
if Info and Info.IsTypedef:
|
if Info and Info.IsTypedef:
|
||||||
if isinstance(Info, CTypeInfo) and Info.BaseType and (not isinstance(Info.BaseType, (t._CTypedef,)) or Info.PtrCount > 0):
|
if isinstance(Info, CTypeInfo) and Info.BaseType and (not isinstance(Info.BaseType, (t._CTypedef,)) or Info.PtrCount > 0):
|
||||||
@@ -233,22 +233,22 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
return Result
|
return Result
|
||||||
return Info.Copy() if Info else CTypeInfo()
|
return Info.Copy() if Info else CTypeInfo()
|
||||||
|
|
||||||
if TypeName not in self.Trans.SymbolTable:
|
if not self.Trans.SymbolTable.has(TypeName):
|
||||||
if not self._IsTModuleType(TypeName) and not (ModulePath and ModulePath.startswith(('t.', 'c.'))):
|
if not self._IsTModuleType(TypeName) and not (ModulePath and ModulePath.startswith(('t.', 'c.'))):
|
||||||
IsEnumMember = False
|
IsEnumMember = False
|
||||||
FirstName = ModuleParts[0]
|
FirstName = ModuleParts[0]
|
||||||
if FirstName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FirstName):
|
||||||
Entry = self.Trans.SymbolTable[FirstName]
|
Entry = self.Trans.SymbolTable[FirstName]
|
||||||
if Entry and Entry.IsEnum:
|
if Entry and Entry.IsEnum:
|
||||||
IsEnumMember = True
|
IsEnumMember = True
|
||||||
|
|
||||||
if not IsEnumMember and FullName in self.Trans.SymbolTable:
|
if not IsEnumMember and self.Trans.SymbolTable.has(FullName):
|
||||||
Entry = self.Trans.SymbolTable[FullName]
|
Entry = self.Trans.SymbolTable[FullName]
|
||||||
if Entry and Entry.IsEnumMember:
|
if Entry and Entry.IsEnumMember:
|
||||||
IsEnumMember = True
|
IsEnumMember = True
|
||||||
|
|
||||||
IsVariable = False
|
IsVariable = False
|
||||||
if not IsEnumMember and FullName in self.Trans.SymbolTable:
|
if not IsEnumMember and self.Trans.SymbolTable.has(FullName):
|
||||||
Entry = self.Trans.SymbolTable[FullName]
|
Entry = self.Trans.SymbolTable[FullName]
|
||||||
if Entry and Entry.TypeCls is not None:
|
if Entry and Entry.TypeCls is not None:
|
||||||
IsVariable = True
|
IsVariable = True
|
||||||
@@ -263,7 +263,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
FirstName = ModuleParts[0]
|
FirstName = ModuleParts[0]
|
||||||
|
|
||||||
FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName
|
FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName
|
||||||
if FullName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FullName):
|
||||||
Info = self.Trans.SymbolTable[FullName]
|
Info = self.Trans.SymbolTable[FullName]
|
||||||
if Info and Info.IsEnumMember:
|
if Info and Info.IsEnumMember:
|
||||||
Result = CTypeInfo()
|
Result = CTypeInfo()
|
||||||
@@ -288,7 +288,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
return Result
|
return Result
|
||||||
return Info.Copy() if Info else CTypeInfo()
|
return Info.Copy() if Info else CTypeInfo()
|
||||||
|
|
||||||
if FirstName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FirstName):
|
||||||
Entry = self.Trans.SymbolTable[FirstName]
|
Entry = self.Trans.SymbolTable[FirstName]
|
||||||
if Entry:
|
if Entry:
|
||||||
Result = CTypeInfo()
|
Result = CTypeInfo()
|
||||||
@@ -307,7 +307,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
EnumName = None
|
EnumName = None
|
||||||
else:
|
else:
|
||||||
EnumName = CTypeHelper.StripTypePrefix(Entry.OriginalType)
|
EnumName = CTypeHelper.StripTypePrefix(Entry.OriginalType)
|
||||||
if EnumName and EnumName in self.Trans.SymbolTable:
|
if EnumName and self.Trans.SymbolTable.has(EnumName):
|
||||||
EnumEntry = self.Trans.SymbolTable[EnumName]
|
EnumEntry = self.Trans.SymbolTable[EnumName]
|
||||||
if EnumEntry and EnumEntry.IsEnum:
|
if EnumEntry and EnumEntry.IsEnum:
|
||||||
Result.BaseType = t._CTypedef(TypeName)
|
Result.BaseType = t._CTypedef(TypeName)
|
||||||
@@ -315,7 +315,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
return Result
|
return Result
|
||||||
|
|
||||||
if FirstName in self.Trans.GeneratedTypes:
|
if FirstName in self.Trans.GeneratedTypes:
|
||||||
if FirstName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FirstName):
|
||||||
Entry = self.Trans.SymbolTable[FirstName]
|
Entry = self.Trans.SymbolTable[FirstName]
|
||||||
if Entry and Entry.IsEnum:
|
if Entry and Entry.IsEnum:
|
||||||
Result.BaseType = t.CEnum(TypeName)
|
Result.BaseType = t.CEnum(TypeName)
|
||||||
@@ -357,12 +357,12 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
AttrInfo.OriginalType = OriginalInfo
|
AttrInfo.OriginalType = OriginalInfo
|
||||||
except Exception:
|
except Exception:
|
||||||
AttrInfo.OriginalType = self._MakeCTypeInfoFromName(Attr().CName) if hasattr(Attr(), 'CName') else None
|
AttrInfo.OriginalType = self._MakeCTypeInfoFromName(Attr().CName) if hasattr(Attr(), 'CName') else None
|
||||||
self.Trans.SymbolTable[AttrName] = AttrInfo
|
self.Trans.SymbolTable.insert(AttrName, AttrInfo)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.Trans._UserTypeModules[ModuleName] = None
|
self.Trans._UserTypeModules[ModuleName] = None
|
||||||
|
|
||||||
FullName = f'{ModulePath}.{TypeName}' if ModulePath else TypeName
|
FullName = f'{ModulePath}.{TypeName}' if ModulePath else TypeName
|
||||||
if FullName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FullName):
|
||||||
Entry = self.Trans.SymbolTable[FullName]
|
Entry = self.Trans.SymbolTable[FullName]
|
||||||
if Entry and Entry.IsTypedef:
|
if Entry and Entry.IsTypedef:
|
||||||
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
||||||
@@ -383,7 +383,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
return Result
|
return Result
|
||||||
return Entry.Copy() if Entry else CTypeInfo()
|
return Entry.Copy() if Entry else CTypeInfo()
|
||||||
|
|
||||||
if TypeName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(TypeName):
|
||||||
Entry = self.Trans.SymbolTable[TypeName]
|
Entry = self.Trans.SymbolTable[TypeName]
|
||||||
if Entry and Entry.IsTypedef:
|
if Entry and Entry.IsTypedef:
|
||||||
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
if isinstance(Entry, CTypeInfo) and Entry.BaseType:
|
||||||
@@ -417,7 +417,7 @@ class HandlesTypeMerge(BaseHandle):
|
|||||||
IsEnumMember = False
|
IsEnumMember = False
|
||||||
if ModuleParts and len(ModuleParts) >= 2:
|
if ModuleParts and len(ModuleParts) >= 2:
|
||||||
FirstName = ModuleParts[0]
|
FirstName = ModuleParts[0]
|
||||||
if FirstName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(FirstName):
|
||||||
Entry = self.Trans.SymbolTable[FirstName]
|
Entry = self.Trans.SymbolTable[FirstName]
|
||||||
if Entry and Entry.IsEnum:
|
if Entry and Entry.IsEnum:
|
||||||
return TypeName
|
return TypeName
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class WithHandle(BaseHandle):
|
|||||||
elif isinstance(context_expr.func, ast.Attribute):
|
elif isinstance(context_expr.func, ast.Attribute):
|
||||||
ClassName = context_expr.func.attr
|
ClassName = context_expr.func.attr
|
||||||
if ClassName and ClassName not in Gen.structs:
|
if ClassName and ClassName not in Gen.structs:
|
||||||
if ClassName in self.Trans.SymbolTable:
|
if self.Trans.SymbolTable.has(ClassName):
|
||||||
SymInfo = self.Trans.SymbolTable[ClassName]
|
SymInfo = self.Trans.SymbolTable[ClassName]
|
||||||
if SymInfo.IsStruct or SymInfo.IsRenum:
|
if SymInfo.IsStruct or SymInfo.IsRenum:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ class BaseGenMixin:
|
|||||||
return existing
|
return existing
|
||||||
if clean_name in {'typedef', 'CType', 'CVolatile', 'CEnum', 'CUnion', 'CStruct', 'enum', 'REnum', 'renum', 'Void', 'void'}:
|
if clean_name in {'typedef', 'CType', 'CVolatile', 'CEnum', 'CUnion', 'CStruct', 'enum', 'REnum', 'renum', 'Void', 'void'}:
|
||||||
return ir.IntType(8)
|
return ir.IntType(8)
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and clean_name in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(clean_name):
|
||||||
Entry = self.SymbolTable[clean_name]
|
Entry = self.SymbolTable[clean_name]
|
||||||
if Entry.IsTypedef:
|
if Entry.IsTypedef:
|
||||||
resolved_str = self._resolve_typedef(clean_name)
|
resolved_str = self._resolve_typedef(clean_name)
|
||||||
@@ -235,7 +235,7 @@ class BaseGenMixin:
|
|||||||
return int(llvm_str[1:])
|
return int(llvm_str[1:])
|
||||||
|
|
||||||
# 2. 再查 SymbolTable(用户定义的 typedef)
|
# 2. 再查 SymbolTable(用户定义的 typedef)
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and name in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(name):
|
||||||
Entry = self.SymbolTable[name]
|
Entry = self.SymbolTable[name]
|
||||||
if Entry.IsTypedef:
|
if Entry.IsTypedef:
|
||||||
if Entry.BaseType:
|
if Entry.BaseType:
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ class StructGenMixin:
|
|||||||
all_classes = set(self.class_methods.keys()) | set(self.class_members.keys())
|
all_classes = set(self.class_methods.keys()) | set(self.class_members.keys())
|
||||||
for ClassName in all_classes:
|
for ClassName in all_classes:
|
||||||
is_packed = ClassName in self.class_packed
|
is_packed = ClassName in self.class_packed
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and ClassName in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(ClassName):
|
||||||
Entry = self.SymbolTable[ClassName]
|
Entry = self.SymbolTable[ClassName]
|
||||||
if Entry.IsExceptionClass:
|
if Entry.IsExceptionClass:
|
||||||
continue
|
continue
|
||||||
@@ -302,7 +302,7 @@ class StructGenMixin:
|
|||||||
|
|
||||||
# Step 4: 创建最终的 structs 并设置正确的成员类型
|
# Step 4: 创建最终的 structs 并设置正确的成员类型
|
||||||
for ClassName in all_classes:
|
for ClassName in all_classes:
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and ClassName in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(ClassName):
|
||||||
Entry = self.SymbolTable[ClassName]
|
Entry = self.SymbolTable[ClassName]
|
||||||
if Entry.IsExceptionClass:
|
if Entry.IsExceptionClass:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class TypeConvertMixin:
|
|||||||
if not name or not hasattr(self, 'SymbolTable') or not self.SymbolTable:
|
if not name or not hasattr(self, 'SymbolTable') or not self.SymbolTable:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
entry = self.SymbolTable.get(name)
|
entry = self.SymbolTable.lookup(name)
|
||||||
if not entry or not isinstance(entry, _CTypeInfo):
|
if not entry or not isinstance(entry, _CTypeInfo):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ class TypeConvertMixin:
|
|||||||
typedef_name = getattr(BaseType, 'value', '') or (type_info.Name if type_info else '')
|
typedef_name = getattr(BaseType, 'value', '') or (type_info.Name if type_info else '')
|
||||||
if typedef_name and hasattr(self, 'SymbolTable') and self.SymbolTable:
|
if typedef_name and hasattr(self, 'SymbolTable') and self.SymbolTable:
|
||||||
from lib.core.Handles.HandlesBase import CTypeInfo as _CTypeInfo
|
from lib.core.Handles.HandlesBase import CTypeInfo as _CTypeInfo
|
||||||
entry = self.SymbolTable.get(typedef_name)
|
entry = self.SymbolTable.lookup(typedef_name)
|
||||||
if entry and isinstance(entry, _CTypeInfo) and entry.BaseType:
|
if entry and isinstance(entry, _CTypeInfo) and entry.BaseType:
|
||||||
if not isinstance(entry.BaseType, _t._CTypedef) or entry.PtrCount > 0:
|
if not isinstance(entry.BaseType, _t._CTypedef) or entry.PtrCount > 0:
|
||||||
return self._base_ctype_to_llvm(entry.BaseType, entry)
|
return self._base_ctype_to_llvm(entry.BaseType, entry)
|
||||||
@@ -173,7 +173,7 @@ class TypeConvertMixin:
|
|||||||
current = type_name
|
current = type_name
|
||||||
while current not in visited:
|
while current not in visited:
|
||||||
visited.add(current)
|
visited.add(current)
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and current in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(current):
|
||||||
Entry = self.SymbolTable[current]
|
Entry = self.SymbolTable[current]
|
||||||
if isinstance(Entry, dict) and Entry.get('type') == 'typedef':
|
if isinstance(Entry, dict) and Entry.get('type') == 'typedef':
|
||||||
OriginalType = Entry.get('OriginalType', '')
|
OriginalType = Entry.get('OriginalType', '')
|
||||||
@@ -394,7 +394,7 @@ class TypeConvertMixin:
|
|||||||
if IsPtr and not isinstance(basic_stripped, ir.VoidType):
|
if IsPtr and not isinstance(basic_stripped, ir.VoidType):
|
||||||
return ir.PointerType(basic_stripped)
|
return ir.PointerType(basic_stripped)
|
||||||
return basic_stripped
|
return basic_stripped
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and type_str in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(type_str):
|
||||||
_Entry = self.SymbolTable[type_str]
|
_Entry = self.SymbolTable[type_str]
|
||||||
if _Entry.IsTypedef:
|
if _Entry.IsTypedef:
|
||||||
resolved_str = self._resolve_typedef(type_str)
|
resolved_str = self._resolve_typedef(type_str)
|
||||||
@@ -429,7 +429,7 @@ class TypeConvertMixin:
|
|||||||
if IsPtr and not isinstance(basic_last, ir.VoidType):
|
if IsPtr and not isinstance(basic_last, ir.VoidType):
|
||||||
return ir.PointerType(basic_last)
|
return ir.PointerType(basic_last)
|
||||||
return basic_last
|
return basic_last
|
||||||
if hasattr(self, 'SymbolTable') and self.SymbolTable and LastPart in self.SymbolTable:
|
if hasattr(self, 'SymbolTable') and self.SymbolTable and self.SymbolTable.has(LastPart):
|
||||||
_Entry = self.SymbolTable[LastPart]
|
_Entry = self.SymbolTable[LastPart]
|
||||||
if _Entry.IsTypedef:
|
if _Entry.IsTypedef:
|
||||||
resolved_str = self._resolve_typedef(LastPart)
|
resolved_str = self._resolve_typedef(LastPart)
|
||||||
|
|||||||
220
lib/core/LLVMTypeMapper.py
Normal file
220
lib/core/LLVMTypeMapper.py
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
"""LLVMTypeMapper — AST 注解节点到 LLVM IR 类型字符串的映射器
|
||||||
|
|
||||||
|
从 SymbolTable 中提取的类型解析逻辑,职责单一:
|
||||||
|
将 Python AST 注解节点翻译为 LLVM IR 类型字符串(如 'i32', 'i8*', '{ i32, i8* }')。
|
||||||
|
|
||||||
|
原 SymbolTable 上的 4 个方法:
|
||||||
|
- _GetLLVMTypeStr → LLVMTypeMapper.get_llvm_type_str
|
||||||
|
- _GetFuncRetTypeStr → LLVMTypeMapper.get_func_ret_type_str
|
||||||
|
- _GetFuncParamTypeStr → LLVMTypeMapper.get_func_param_type_str
|
||||||
|
- _ResolveTypedefValueType → LLVMTypeMapper.resolve_typedef_value_type
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import ast
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from lib.core.SymbolTable import SymbolTable
|
||||||
|
|
||||||
|
from lib.core.Handles.HandlesBase import CTypeInfo, CTypeHelper
|
||||||
|
|
||||||
|
|
||||||
|
class LLVMTypeMapper:
|
||||||
|
"""AST 注解节点 → LLVM IR 类型字符串 映射器"""
|
||||||
|
|
||||||
|
def __init__(self, symtab: SymbolTable):
|
||||||
|
self._symtab = symtab
|
||||||
|
|
||||||
|
# ==================================================================
|
||||||
|
# 公共 API
|
||||||
|
# ==================================================================
|
||||||
|
|
||||||
|
def get_llvm_type_str(self, node) -> str:
|
||||||
|
"""将 AST 注解节点转换为 LLVM IR 类型字符串"""
|
||||||
|
if node is None:
|
||||||
|
self._symtab.diagnostics.warn('', 0, "类型注解为 None,回退到 i32")
|
||||||
|
return 'i32'
|
||||||
|
if isinstance(node, ast.Name):
|
||||||
|
return self._resolve_name(node)
|
||||||
|
elif isinstance(node, ast.Attribute):
|
||||||
|
return self._resolve_attribute(node)
|
||||||
|
elif isinstance(node, ast.Subscript):
|
||||||
|
return self._resolve_subscript(node)
|
||||||
|
elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
|
||||||
|
return self._resolve_bitor(node)
|
||||||
|
elif isinstance(node, ast.Constant):
|
||||||
|
if isinstance(node.value, bool):
|
||||||
|
return 'i8'
|
||||||
|
return 'i32'
|
||||||
|
elif isinstance(node, ast.Call):
|
||||||
|
return self._resolve_call(node)
|
||||||
|
self._symtab.diagnostics.warn('', 0, f"无法解析类型节点 {type(node).__name__},回退到 i32")
|
||||||
|
return 'i32'
|
||||||
|
|
||||||
|
def get_func_ret_type_str(self, returns_node) -> str:
|
||||||
|
"""提取函数返回类型的 LLVM 字符串"""
|
||||||
|
if returns_node is None:
|
||||||
|
return 'i32'
|
||||||
|
if isinstance(returns_node, ast.BinOp) and isinstance(returns_node.op, ast.BitOr):
|
||||||
|
left_str = self.get_llvm_type_str(returns_node.left)
|
||||||
|
right_str = self.get_llvm_type_str(returns_node.right)
|
||||||
|
if right_str and right_str.endswith('*'):
|
||||||
|
return right_str
|
||||||
|
if left_str and left_str.endswith('*'):
|
||||||
|
return left_str
|
||||||
|
if left_str and left_str not in ('i32', 'void', 'i64'):
|
||||||
|
return left_str
|
||||||
|
if right_str and right_str not in ('i32', 'void', 'i64'):
|
||||||
|
return right_str
|
||||||
|
return left_str
|
||||||
|
result = self.get_llvm_type_str(returns_node)
|
||||||
|
return result if result else 'i32'
|
||||||
|
|
||||||
|
def get_func_param_type_str(self, annotation_node) -> str:
|
||||||
|
"""提取函数参数类型的 LLVM 字符串"""
|
||||||
|
if annotation_node is None:
|
||||||
|
return 'i8*'
|
||||||
|
if isinstance(annotation_node, ast.BinOp) and isinstance(annotation_node.op, ast.BitOr):
|
||||||
|
left_str = self.get_llvm_type_str(annotation_node.left)
|
||||||
|
right_str = self.get_llvm_type_str(annotation_node.right)
|
||||||
|
if right_str and right_str.endswith('*'):
|
||||||
|
return right_str
|
||||||
|
if left_str and left_str.endswith('*'):
|
||||||
|
return left_str
|
||||||
|
if right_str and right_str not in ('i32', 'void', 'i64'):
|
||||||
|
return right_str
|
||||||
|
if left_str and left_str not in ('i32', 'void', 'i64'):
|
||||||
|
return left_str
|
||||||
|
if left_str and left_str.endswith('*'):
|
||||||
|
return left_str
|
||||||
|
return right_str if right_str else left_str
|
||||||
|
result = self.get_llvm_type_str(annotation_node)
|
||||||
|
return result if result else 'i8*'
|
||||||
|
|
||||||
|
def resolve_typedef_value_type(self, node) -> str:
|
||||||
|
"""解析 typedef 值表达式的 C 类型字符串"""
|
||||||
|
if node is None:
|
||||||
|
return ''
|
||||||
|
if isinstance(node, ast.Name):
|
||||||
|
if node.id in self._symtab:
|
||||||
|
Entry = self._symtab[node.id]
|
||||||
|
if Entry.IsTypedef and Entry.OriginalType:
|
||||||
|
return Entry.OriginalType
|
||||||
|
return ''
|
||||||
|
if isinstance(node, ast.Attribute):
|
||||||
|
if isinstance(node.value, ast.Name) and node.value.id == 't':
|
||||||
|
CName = CTypeHelper.GetCName(node.attr)
|
||||||
|
if CName and CName == '*':
|
||||||
|
return 'ptr'
|
||||||
|
if CName:
|
||||||
|
return CName
|
||||||
|
return ''
|
||||||
|
if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
|
||||||
|
left_str = self.resolve_typedef_value_type(node.left)
|
||||||
|
right_str = self.resolve_typedef_value_type(node.right)
|
||||||
|
if right_str == 'ptr' or (right_str and right_str.endswith('*')):
|
||||||
|
base = left_str if left_str and left_str != 'ptr' else ''
|
||||||
|
return base + ' *' if base else 'void *'
|
||||||
|
if left_str == 'ptr' or (left_str and left_str.endswith('*')):
|
||||||
|
base = right_str if right_str and right_str != 'ptr' else ''
|
||||||
|
return base + ' *' if base else 'void *'
|
||||||
|
if right_str and right_str not in ('ptr', 'void', 'i32', 'i64'):
|
||||||
|
return right_str
|
||||||
|
if left_str and left_str not in ('ptr', 'void', 'i32', 'i64'):
|
||||||
|
return left_str
|
||||||
|
return left_str if left_str else right_str
|
||||||
|
return ''
|
||||||
|
|
||||||
|
# ==================================================================
|
||||||
|
# 内部解析方法
|
||||||
|
# ==================================================================
|
||||||
|
|
||||||
|
def _resolve_name(self, node: ast.Name) -> str:
|
||||||
|
"""解析 ast.Name 节点"""
|
||||||
|
id_map = {
|
||||||
|
'str': 'i8*', 'int': 'i32', 'bool': 'i8',
|
||||||
|
'float': 'double', 'None': 'void',
|
||||||
|
'UINT8PTR': 'i8*', 'INT8PTR': 'i8*', 'BYTEPTR': 'i8*',
|
||||||
|
'UINT16PTR': 'i16*', 'INT16PTR': 'i16*',
|
||||||
|
'UINT32PTR': 'i32*', 'INT32PTR': 'i32*',
|
||||||
|
'UINT64PTR': 'i64*', 'INT64PTR': 'i64*',
|
||||||
|
}
|
||||||
|
if node.id in id_map:
|
||||||
|
return id_map[node.id]
|
||||||
|
# 查找 SymbolTable 中的 typedef
|
||||||
|
if node.id in self._symtab:
|
||||||
|
entry = self._symtab[node.id]
|
||||||
|
if entry and entry.IsTypedef and entry.OriginalType:
|
||||||
|
if isinstance(entry.OriginalType, CTypeInfo) and entry.OriginalType.IsFuncPtr:
|
||||||
|
return 'i8*'
|
||||||
|
elif isinstance(entry.OriginalType, CTypeInfo) and entry.OriginalType.BaseType:
|
||||||
|
return entry.OriginalType.ToString()
|
||||||
|
elif isinstance(entry.OriginalType, str):
|
||||||
|
return entry.OriginalType
|
||||||
|
self._symtab.diagnostics.warn('', 0, f"无法解析 Name 类型 '{node.id}',回退到 i32")
|
||||||
|
return 'i32'
|
||||||
|
|
||||||
|
def _resolve_attribute(self, node: ast.Attribute) -> str:
|
||||||
|
"""解析 ast.Attribute 节点"""
|
||||||
|
attr_name = node.attr if hasattr(node, 'attr') else ''
|
||||||
|
from lib.includes.t import CTypeRegistry
|
||||||
|
llvm_str = CTypeRegistry.NameToLLVM(attr_name)
|
||||||
|
if llvm_str is not None:
|
||||||
|
return llvm_str
|
||||||
|
if attr_name in ('CState', 'CDefine', 'CTypedef', 'CExtern', 'CStatic', 'CConst', 'State'):
|
||||||
|
return ''
|
||||||
|
if attr_name in ('CCharPtr', 'CIntPtr', 'CVoidPtr', 'CArrayPtr'):
|
||||||
|
return 'i8*'
|
||||||
|
if attr_name == 'CVoidPtr':
|
||||||
|
return 'i8*'
|
||||||
|
if attr_name and attr_name[0].isupper() and attr_name not in CTypeRegistry._name_to_class:
|
||||||
|
return f'%struct.{attr_name}*'
|
||||||
|
if attr_name and attr_name not in CTypeRegistry._name_to_class:
|
||||||
|
return f'%struct.{attr_name}*'
|
||||||
|
self._symtab.diagnostics.warn('', 0, f"无法解析 Attribute 类型 '{attr_name}',回退到 i32")
|
||||||
|
return 'i32'
|
||||||
|
|
||||||
|
def _resolve_subscript(self, node: ast.Subscript) -> str:
|
||||||
|
"""解析 ast.Subscript 节点"""
|
||||||
|
if isinstance(node.value, ast.Name) and node.value.id == 'tuple':
|
||||||
|
slice_node = node.slice
|
||||||
|
elem_types = []
|
||||||
|
if isinstance(slice_node, ast.Tuple):
|
||||||
|
for elt in slice_node.elts:
|
||||||
|
elem_types.append(self.get_llvm_type_str(elt))
|
||||||
|
else:
|
||||||
|
elem_types.append(self.get_llvm_type_str(slice_node))
|
||||||
|
if elem_types:
|
||||||
|
return '{ ' + ', '.join(elem_types) + ' }'
|
||||||
|
if isinstance(node.value, ast.Name) and node.value.id == 'list':
|
||||||
|
slice_node = node.slice
|
||||||
|
if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) >= 1:
|
||||||
|
elem_type = self.get_llvm_type_str(slice_node.elts[0])
|
||||||
|
else:
|
||||||
|
elem_type = self.get_llvm_type_str(slice_node)
|
||||||
|
return elem_type + '*'
|
||||||
|
self._symtab.diagnostics.warn('', 0, "无法解析 Subscript 类型,回退到 i32")
|
||||||
|
return 'i32'
|
||||||
|
|
||||||
|
def _resolve_bitor(self, node: ast.BinOp) -> str:
|
||||||
|
"""解析 ast.BinOp(BitOr) 节点"""
|
||||||
|
left = self.get_llvm_type_str(node.left)
|
||||||
|
right = self.get_llvm_type_str(node.right)
|
||||||
|
if right and right.endswith('*'):
|
||||||
|
return right
|
||||||
|
if left and left.endswith('*'):
|
||||||
|
return left
|
||||||
|
if left and left not in ('i32', 'void', 'i64'):
|
||||||
|
return left
|
||||||
|
if right and right not in ('i32', 'void', 'i64'):
|
||||||
|
return right
|
||||||
|
return left if left else right
|
||||||
|
|
||||||
|
def _resolve_call(self, node: ast.Call) -> str:
|
||||||
|
"""解析 ast.Call 节点"""
|
||||||
|
if isinstance(node.func, ast.Attribute):
|
||||||
|
if hasattr(node.func.value, 'id') and node.func.value.id == 't':
|
||||||
|
return self.get_llvm_type_str(ast.Attribute(value=ast.Name(id='t'), attr=node.func.attr))
|
||||||
|
self._symtab.diagnostics.warn('', 0, "无法解析 Call 类型,回退到 i32")
|
||||||
|
return 'i32'
|
||||||
@@ -19,6 +19,9 @@ class SymbolTable:
|
|||||||
self._symbols: Dict[str, CTypeInfo] = {}
|
self._symbols: Dict[str, CTypeInfo] = {}
|
||||||
from lib.core.DiagnosticCollector import DiagnosticCollector
|
from lib.core.DiagnosticCollector import DiagnosticCollector
|
||||||
self.diagnostics = DiagnosticCollector()
|
self.diagnostics = DiagnosticCollector()
|
||||||
|
from lib.core.LLVMTypeMapper import LLVMTypeMapper
|
||||||
|
self._type_mapper = LLVMTypeMapper(self)
|
||||||
|
self.import_aliases: Dict[str, str] = {}
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._symbols.clear()
|
self._symbols.clear()
|
||||||
@@ -69,6 +72,99 @@ class SymbolTable:
|
|||||||
|
|
||||||
def __iter__(self) -> Iterator[str]:
|
def __iter__(self) -> Iterator[str]:
|
||||||
return iter(self._symbols)
|
return iter(self._symbols)
|
||||||
|
|
||||||
|
# ==================================================================
|
||||||
|
# 服务接口 — 语义化的符号查询与操作方法
|
||||||
|
# ==================================================================
|
||||||
|
|
||||||
|
def lookup(self, name: str) -> CTypeInfo | None:
|
||||||
|
"""查找符号,不存在返回 None(替代 `SymbolTable.get(name)`)"""
|
||||||
|
return self._symbols.get(name)
|
||||||
|
|
||||||
|
def has(self, name: str) -> bool:
|
||||||
|
"""检查符号是否存在(替代 `name in SymbolTable`)"""
|
||||||
|
return name in self._symbols
|
||||||
|
|
||||||
|
def lookup_struct(self, name: str) -> CTypeInfo | None:
|
||||||
|
"""查找结构体符号,非结构体返回 None"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
if entry and (entry.IsStruct or entry.IsCpythonObject):
|
||||||
|
return entry
|
||||||
|
return None
|
||||||
|
|
||||||
|
def lookup_enum(self, name: str) -> CTypeInfo | None:
|
||||||
|
"""查找枚举符号,非枚举返回 None"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
if entry and entry.IsEnum:
|
||||||
|
return entry
|
||||||
|
return None
|
||||||
|
|
||||||
|
def lookup_typedef(self, name: str) -> CTypeInfo | None:
|
||||||
|
"""查找 typedef 符号,非 typedef 返回 None"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
if entry and entry.IsTypedef:
|
||||||
|
return entry
|
||||||
|
return None
|
||||||
|
|
||||||
|
def lookup_function(self, name: str) -> CTypeInfo | None:
|
||||||
|
"""查找函数符号,非函数返回 None"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
if entry and (entry.IsFunction or entry.IsFuncPtr):
|
||||||
|
return entry
|
||||||
|
return None
|
||||||
|
|
||||||
|
def lookup_define(self, name: str) -> CTypeInfo | None:
|
||||||
|
"""查找常量定义符号,非 define 返回 None"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
if entry and entry.IsDefine:
|
||||||
|
return entry
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_struct(self, name: str) -> bool:
|
||||||
|
"""检查名称是否为结构体"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
return entry is not None and (entry.IsStruct or entry.IsCpythonObject)
|
||||||
|
|
||||||
|
def is_enum(self, name: str) -> bool:
|
||||||
|
"""检查名称是否为枚举"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
return entry is not None and entry.IsEnum
|
||||||
|
|
||||||
|
def is_typedef(self, name: str) -> bool:
|
||||||
|
"""检查名称是否为 typedef"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
return entry is not None and entry.IsTypedef
|
||||||
|
|
||||||
|
def is_function(self, name: str) -> bool:
|
||||||
|
"""检查名称是否为函数"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
return entry is not None and (entry.IsFunction or entry.IsFuncPtr)
|
||||||
|
|
||||||
|
def is_variable(self, name: str) -> bool:
|
||||||
|
"""检查名称是否为变量"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
return entry is not None and entry.IsVariable
|
||||||
|
|
||||||
|
def is_define(self, name: str) -> bool:
|
||||||
|
"""检查名称是否为常量定义"""
|
||||||
|
entry = self._symbols.get(name)
|
||||||
|
return entry is not None and entry.IsDefine
|
||||||
|
|
||||||
|
def insert(self, name: str, info: CTypeInfo):
|
||||||
|
"""插入符号(替代 `SymbolTable[name] = info`)"""
|
||||||
|
self._symbols[name] = info
|
||||||
|
|
||||||
|
def resolve_alias(self, module_path: str) -> str:
|
||||||
|
"""解析 import 别名,无别名返回原路径"""
|
||||||
|
return self.import_aliases.get(module_path, module_path)
|
||||||
|
|
||||||
|
def find_by_suffix(self, suffix: str) -> list[tuple[str, CTypeInfo]]:
|
||||||
|
"""按名称后缀模糊查找符号(替代遍历 + endswith 匹配)"""
|
||||||
|
results = []
|
||||||
|
for name, info in self._symbols.items():
|
||||||
|
if name.endswith(suffix):
|
||||||
|
results.append((name, info))
|
||||||
|
return results
|
||||||
|
|
||||||
def ToDict(self) -> Dict[str, Any]:
|
def ToDict(self) -> Dict[str, Any]:
|
||||||
"""序列化为字典格式"""
|
"""序列化为字典格式"""
|
||||||
@@ -217,183 +313,24 @@ class SymbolTable:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
# ==================================================================
|
# ==================================================================
|
||||||
# 类型解析辅助方法(供 TypeResolver 通过 SymbolTable 引用调用)
|
# 类型解析辅助方法(委托到 LLVMTypeMapper)
|
||||||
# ==================================================================
|
# ==================================================================
|
||||||
|
|
||||||
def _GetLLVMTypeStr(self, node):
|
def _GetLLVMTypeStr(self, node):
|
||||||
if node is None:
|
return self._type_mapper.get_llvm_type_str(node)
|
||||||
self.diagnostics.warn('', 0, "类型注解为 None,回退到 i32")
|
|
||||||
return 'i32'
|
|
||||||
if isinstance(node, ast.Name):
|
|
||||||
if node.id == 'str':
|
|
||||||
return 'i8*'
|
|
||||||
elif node.id == 'int':
|
|
||||||
return 'i32'
|
|
||||||
elif node.id == 'bool':
|
|
||||||
return 'i8'
|
|
||||||
elif node.id == 'float':
|
|
||||||
return 'double'
|
|
||||||
elif node.id == 'None':
|
|
||||||
return 'void'
|
|
||||||
elif node.id in ('UINT8PTR', 'INT8PTR', 'BYTEPTR'):
|
|
||||||
return 'i8*'
|
|
||||||
elif node.id in ('UINT16PTR', 'INT16PTR'):
|
|
||||||
return 'i16*'
|
|
||||||
elif node.id in ('UINT32PTR', 'INT32PTR'):
|
|
||||||
return 'i32*'
|
|
||||||
elif node.id in ('UINT64PTR', 'INT64PTR'):
|
|
||||||
return 'i64*'
|
|
||||||
else:
|
|
||||||
if node.id in self:
|
|
||||||
entry = self[node.id]
|
|
||||||
if entry and entry.IsTypedef and entry.OriginalType:
|
|
||||||
if isinstance(entry.OriginalType, CTypeInfo) and entry.OriginalType.IsFuncPtr:
|
|
||||||
return 'i8*'
|
|
||||||
elif isinstance(entry.OriginalType, CTypeInfo) and entry.OriginalType.BaseType:
|
|
||||||
return entry.OriginalType.ToString()
|
|
||||||
elif isinstance(entry.OriginalType, str):
|
|
||||||
return entry.OriginalType
|
|
||||||
self.diagnostics.warn('', 0, f"无法解析 Name 类型 '{node.id}',回退到 i32")
|
|
||||||
return 'i32'
|
|
||||||
elif isinstance(node, ast.Attribute):
|
|
||||||
attr_name = node.attr if hasattr(node, 'attr') else ''
|
|
||||||
from lib.includes.t import CTypeRegistry
|
|
||||||
llvm_str = CTypeRegistry.NameToLLVM(attr_name)
|
|
||||||
if llvm_str is not None:
|
|
||||||
return llvm_str
|
|
||||||
if attr_name in ('CState', 'CDefine', 'CTypedef', 'CExtern', 'CStatic', 'CConst', 'State'):
|
|
||||||
return ''
|
|
||||||
if attr_name in ('CCharPtr', 'CIntPtr', 'CVoidPtr', 'CArrayPtr'):
|
|
||||||
return 'i8*'
|
|
||||||
if attr_name == 'CVoidPtr':
|
|
||||||
return 'i8*'
|
|
||||||
if attr_name and attr_name[0].isupper() and attr_name not in CTypeRegistry._name_to_class:
|
|
||||||
return f'%struct.{attr_name}*'
|
|
||||||
if attr_name and attr_name not in CTypeRegistry._name_to_class:
|
|
||||||
return f'%struct.{attr_name}*'
|
|
||||||
self.diagnostics.warn('', 0, f"无法解析 Attribute 类型 '{attr_name}',回退到 i32")
|
|
||||||
return 'i32'
|
|
||||||
elif isinstance(node, ast.Subscript):
|
|
||||||
if isinstance(node.value, ast.Name) and node.value.id == 'tuple':
|
|
||||||
slice_node = node.slice
|
|
||||||
elem_types = []
|
|
||||||
if isinstance(slice_node, ast.Tuple):
|
|
||||||
for elt in slice_node.elts:
|
|
||||||
elem_types.append(self._GetLLVMTypeStr(elt))
|
|
||||||
else:
|
|
||||||
elem_types.append(self._GetLLVMTypeStr(slice_node))
|
|
||||||
if elem_types:
|
|
||||||
return '{ ' + ', '.join(elem_types) + ' }'
|
|
||||||
if isinstance(node.value, ast.Name) and node.value.id == 'list':
|
|
||||||
slice_node = node.slice
|
|
||||||
if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) >= 1:
|
|
||||||
elem_type = self._GetLLVMTypeStr(slice_node.elts[0])
|
|
||||||
else:
|
|
||||||
elem_type = self._GetLLVMTypeStr(slice_node)
|
|
||||||
return elem_type + '*'
|
|
||||||
self.diagnostics.warn('', 0, f"无法解析 Subscript 类型,回退到 i32")
|
|
||||||
return 'i32'
|
|
||||||
elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
|
|
||||||
left = self._GetLLVMTypeStr(node.left)
|
|
||||||
right = self._GetLLVMTypeStr(node.right)
|
|
||||||
if right and right.endswith('*'):
|
|
||||||
return right
|
|
||||||
if left and left.endswith('*'):
|
|
||||||
return left
|
|
||||||
if left and left not in ('i32', 'void', 'i64'):
|
|
||||||
return left
|
|
||||||
if right and right not in ('i32', 'void', 'i64'):
|
|
||||||
return right
|
|
||||||
return left if left else right
|
|
||||||
elif isinstance(node, ast.Constant):
|
|
||||||
if isinstance(node.value, bool):
|
|
||||||
return 'i8'
|
|
||||||
return 'i32'
|
|
||||||
elif isinstance(node, ast.Call):
|
|
||||||
if isinstance(node.func, ast.Attribute):
|
|
||||||
if hasattr(node.func.value, 'id') and node.func.value.id == 't':
|
|
||||||
return self._GetLLVMTypeStr(ast.Attribute(value=ast.Name(id='t'), attr=node.func.attr))
|
|
||||||
self.diagnostics.warn('', 0, "无法解析 Call 类型,回退到 i32")
|
|
||||||
return 'i32'
|
|
||||||
self.diagnostics.warn('', 0, f"无法解析类型节点 {type(node).__name__},回退到 i32")
|
|
||||||
return 'i32'
|
|
||||||
|
|
||||||
def _GetFuncRetTypeStr(self, returns_node):
|
def _GetFuncRetTypeStr(self, returns_node):
|
||||||
if returns_node is None:
|
return self._type_mapper.get_func_ret_type_str(returns_node)
|
||||||
return 'i32'
|
|
||||||
actual = returns_node
|
|
||||||
if isinstance(returns_node, ast.BinOp) and isinstance(returns_node.op, ast.BitOr):
|
|
||||||
left_str = self._GetLLVMTypeStr(returns_node.left)
|
|
||||||
right_str = self._GetLLVMTypeStr(returns_node.right)
|
|
||||||
if right_str and right_str.endswith('*'):
|
|
||||||
return right_str
|
|
||||||
if left_str and left_str.endswith('*'):
|
|
||||||
return left_str
|
|
||||||
if left_str and left_str not in ('i32', 'void', 'i64'):
|
|
||||||
return left_str
|
|
||||||
if right_str and right_str not in ('i32', 'void', 'i64'):
|
|
||||||
return right_str
|
|
||||||
return left_str
|
|
||||||
result = self._GetLLVMTypeStr(actual)
|
|
||||||
return result if result else 'i32'
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _CheckAnnotationHasCInline(annotation_node) -> bool:
|
def _CheckAnnotationHasCInline(annotation_node) -> bool:
|
||||||
return _CheckAnnotationHasCInline(annotation_node)
|
return _CheckAnnotationHasCInline(annotation_node)
|
||||||
|
|
||||||
def _GetFuncParamTypeStr(self, annotation_node):
|
def _GetFuncParamTypeStr(self, annotation_node):
|
||||||
if annotation_node is None:
|
return self._type_mapper.get_func_param_type_str(annotation_node)
|
||||||
return 'i8*'
|
|
||||||
actual = annotation_node
|
|
||||||
if isinstance(annotation_node, ast.BinOp) and isinstance(annotation_node.op, ast.BitOr):
|
|
||||||
left_str = self._GetLLVMTypeStr(annotation_node.left)
|
|
||||||
right_str = self._GetLLVMTypeStr(annotation_node.right)
|
|
||||||
if right_str and right_str.endswith('*'):
|
|
||||||
return right_str
|
|
||||||
if left_str and left_str.endswith('*'):
|
|
||||||
return left_str
|
|
||||||
if right_str and right_str not in ('i32', 'void', 'i64'):
|
|
||||||
return right_str
|
|
||||||
if left_str and left_str not in ('i32', 'void', 'i64'):
|
|
||||||
return left_str
|
|
||||||
if left_str and left_str.endswith('*'):
|
|
||||||
return left_str
|
|
||||||
return right_str if right_str else left_str
|
|
||||||
result = self._GetLLVMTypeStr(actual)
|
|
||||||
return result if result else 'i8*'
|
|
||||||
|
|
||||||
def _ResolveTypedefValueType(self, node):
|
def _ResolveTypedefValueType(self, node):
|
||||||
if node is None:
|
return self._type_mapper.resolve_typedef_value_type(node)
|
||||||
return ''
|
|
||||||
if isinstance(node, ast.Name):
|
|
||||||
if node.id in self:
|
|
||||||
Entry = self[node.id]
|
|
||||||
if Entry.IsTypedef and Entry.OriginalType:
|
|
||||||
return Entry.OriginalType
|
|
||||||
return ''
|
|
||||||
if isinstance(node, ast.Attribute):
|
|
||||||
if isinstance(node.value, ast.Name) and node.value.id == 't':
|
|
||||||
CName = CTypeHelper.GetCName(node.attr)
|
|
||||||
if CName and CName == '*':
|
|
||||||
return 'ptr'
|
|
||||||
if CName:
|
|
||||||
return CName
|
|
||||||
return ''
|
|
||||||
if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr):
|
|
||||||
left_str = self._ResolveTypedefValueType(node.left)
|
|
||||||
right_str = self._ResolveTypedefValueType(node.right)
|
|
||||||
if right_str == 'ptr' or (right_str and right_str.endswith('*')):
|
|
||||||
base = left_str if left_str and left_str != 'ptr' else ''
|
|
||||||
return base + ' *' if base else 'void *'
|
|
||||||
if left_str == 'ptr' or (left_str and left_str.endswith('*')):
|
|
||||||
base = right_str if right_str and right_str != 'ptr' else ''
|
|
||||||
return base + ' *' if base else 'void *'
|
|
||||||
if right_str and right_str not in ('ptr', 'void', 'i32', 'i64'):
|
|
||||||
return right_str
|
|
||||||
if left_str and left_str not in ('ptr', 'void', 'i32', 'i64'):
|
|
||||||
return left_str
|
|
||||||
return left_str if left_str else right_str
|
|
||||||
return ''
|
|
||||||
|
|
||||||
# ==================================================================
|
# ==================================================================
|
||||||
# 符号插入方法(供 SymbolInserter / PackageReexporter 调用)
|
# 符号插入方法(供 SymbolInserter / PackageReexporter 调用)
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ class TypeResolver:
|
|||||||
|
|
||||||
def __init__(self, symbol_table: SymbolTable):
|
def __init__(self, symbol_table: SymbolTable):
|
||||||
self._symtab = symbol_table
|
self._symtab = symbol_table
|
||||||
|
from lib.core.LLVMTypeMapper import LLVMTypeMapper
|
||||||
|
self._type_mapper = LLVMTypeMapper(symbol_table)
|
||||||
|
|
||||||
def resolve(self, module_symbols: ModuleSymbols) -> ModuleSymbols:
|
def resolve(self, module_symbols: ModuleSymbols) -> ModuleSymbols:
|
||||||
"""解析所有类型信息,就地更新 ModuleSymbols"""
|
"""解析所有类型信息,就地更新 ModuleSymbols"""
|
||||||
@@ -119,8 +121,8 @@ class TypeResolver:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(td.value, ast.BinOp) and isinstance(td.value.op, ast.BitOr):
|
if isinstance(td.value, ast.BinOp) and isinstance(td.value.op, ast.BitOr):
|
||||||
left_type = self._symtab._ResolveTypedefValueType(td.value.left)
|
left_type = self._type_mapper.resolve_typedef_value_type(td.value.left)
|
||||||
right_type = self._symtab._ResolveTypedefValueType(td.value.right)
|
right_type = self._type_mapper.resolve_typedef_value_type(td.value.right)
|
||||||
is_ptr_type = right_type == 'ptr' or left_type == 'ptr'
|
is_ptr_type = right_type == 'ptr' or left_type == 'ptr'
|
||||||
if is_ptr_type:
|
if is_ptr_type:
|
||||||
base_name = left_type if left_type != 'ptr' else (right_type if right_type != 'ptr' else '')
|
base_name = left_type if left_type != 'ptr' else (right_type if right_type != 'ptr' else '')
|
||||||
@@ -156,11 +158,11 @@ class TypeResolver:
|
|||||||
|
|
||||||
def _resolve_function(self, func: FuncSymbolData):
|
def _resolve_function(self, func: FuncSymbolData):
|
||||||
"""解析函数的返回类型和参数类型"""
|
"""解析函数的返回类型和参数类型"""
|
||||||
func.ret_type = self._symtab._GetFuncRetTypeStr(func.returns_node)
|
func.ret_type = self._type_mapper.get_func_ret_type_str(func.returns_node)
|
||||||
func.param_types = []
|
func.param_types = []
|
||||||
for _arg_name, annotation in func.params:
|
for _arg_name, annotation in func.params:
|
||||||
if annotation:
|
if annotation:
|
||||||
func.param_types.append(self._symtab._GetFuncParamTypeStr(annotation))
|
func.param_types.append(self._type_mapper.get_func_param_type_str(annotation))
|
||||||
else:
|
else:
|
||||||
func.param_types.append('i8*')
|
func.param_types.append('i8*')
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class AnnotationLoaderMixin:
|
|||||||
EnumNode.set('source', 'annotation_module')
|
EnumNode.set('source', 'annotation_module')
|
||||||
EnumNode.library_name = lib_name
|
EnumNode.library_name = lib_name
|
||||||
EnumNode.file = source_file
|
EnumNode.file = source_file
|
||||||
self.SymbolTable[AttrName] = EnumNode
|
self.SymbolTable.insert(AttrName, EnumNode)
|
||||||
if lib_name:
|
if lib_name:
|
||||||
FullName = f'{lib_name}.{AttrName}'
|
FullName = f'{lib_name}.{AttrName}'
|
||||||
full_EnumNode = CTypeInfo()
|
full_EnumNode = CTypeInfo()
|
||||||
@@ -65,7 +65,7 @@ class AnnotationLoaderMixin:
|
|||||||
full_EnumNode.set('source', 'annotation_module')
|
full_EnumNode.set('source', 'annotation_module')
|
||||||
full_EnumNode.library_name = lib_name
|
full_EnumNode.library_name = lib_name
|
||||||
full_EnumNode.file = source_file
|
full_EnumNode.file = source_file
|
||||||
self.SymbolTable[FullName] = full_EnumNode
|
self.SymbolTable.insert(FullName, full_EnumNode)
|
||||||
# 枚举成员也需要注册
|
# 枚举成员也需要注册
|
||||||
for MemberName in dir(attr):
|
for MemberName in dir(attr):
|
||||||
if not MemberName.startswith('_'):
|
if not MemberName.startswith('_'):
|
||||||
@@ -78,12 +78,12 @@ class AnnotationLoaderMixin:
|
|||||||
MemberNode.EnumName = AttrName
|
MemberNode.EnumName = AttrName
|
||||||
MemberNode.library_name = lib_name
|
MemberNode.library_name = lib_name
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.SymbolTable[MemberName] = MemberNode
|
self.SymbolTable.insert(MemberName, MemberNode)
|
||||||
self.SymbolTable[f"{AttrName}.{MemberName}"] = MemberNode
|
self.SymbolTable.insert(f"{AttrName}.{MemberName}", MemberNode)
|
||||||
self.SymbolTable[f"{AttrName}_{MemberName}"] = MemberNode
|
self.SymbolTable.insert(f"{AttrName}_{MemberName}", MemberNode)
|
||||||
if lib_name:
|
if lib_name:
|
||||||
self.SymbolTable[f"{lib_name}.{AttrName}.{MemberName}"] = MemberNode
|
self.SymbolTable.insert(f"{lib_name}.{AttrName}.{MemberName}", MemberNode)
|
||||||
self.SymbolTable[f"{lib_name}_{AttrName}_{MemberName}"] = MemberNode
|
self.SymbolTable.insert(f"{lib_name}_{AttrName}_{MemberName}", MemberNode)
|
||||||
count += 1
|
count += 1
|
||||||
# 检查是否是 CType 子类(typedef 别名)
|
# 检查是否是 CType 子类(typedef 别名)
|
||||||
elif isinstance(attr, type) and issubclass(attr, CType) and attr is not CType:
|
elif isinstance(attr, type) and issubclass(attr, CType) and attr is not CType:
|
||||||
@@ -101,7 +101,7 @@ class AnnotationLoaderMixin:
|
|||||||
TypedefNode.set('source', 'annotation_module')
|
TypedefNode.set('source', 'annotation_module')
|
||||||
TypedefNode.library_name = lib_name
|
TypedefNode.library_name = lib_name
|
||||||
TypedefNode.file = source_file
|
TypedefNode.file = source_file
|
||||||
self.SymbolTable[AttrName] = TypedefNode
|
self.SymbolTable.insert(AttrName, TypedefNode)
|
||||||
if lib_name and FullName != AttrName:
|
if lib_name and FullName != AttrName:
|
||||||
FullTypedef_node = CTypeInfo()
|
FullTypedef_node = CTypeInfo()
|
||||||
FullTypedef_node.Name = FullName
|
FullTypedef_node.Name = FullName
|
||||||
@@ -110,7 +110,7 @@ class AnnotationLoaderMixin:
|
|||||||
FullTypedef_node.set('source', 'annotation_module')
|
FullTypedef_node.set('source', 'annotation_module')
|
||||||
FullTypedef_node.library_name = lib_name
|
FullTypedef_node.library_name = lib_name
|
||||||
FullTypedef_node.file = source_file
|
FullTypedef_node.file = source_file
|
||||||
self.SymbolTable[FullName] = FullTypedef_node
|
self.SymbolTable.insert(FullName, FullTypedef_node)
|
||||||
count += 1
|
count += 1
|
||||||
# 检查是否是下划线前缀的 CType 子类(如 _CTypedef -> CTypedef)
|
# 检查是否是下划线前缀的 CType 子类(如 _CTypedef -> CTypedef)
|
||||||
elif AttrName.startswith('_') and len(AttrName) > 1:
|
elif AttrName.startswith('_') and len(AttrName) > 1:
|
||||||
@@ -119,7 +119,7 @@ class AnnotationLoaderMixin:
|
|||||||
if PublicAttr is not None and not isinstance(attr, type):
|
if PublicAttr is not None and not isinstance(attr, type):
|
||||||
continue
|
continue
|
||||||
if isinstance(attr, type) and issubclass(attr, CType) and attr is not CType:
|
if isinstance(attr, type) and issubclass(attr, CType) and attr is not CType:
|
||||||
if PublicName not in self.SymbolTable:
|
if not self.SymbolTable.has(PublicName):
|
||||||
if lib_name:
|
if lib_name:
|
||||||
FullName = f'{lib_name}.{PublicName}'
|
FullName = f'{lib_name}.{PublicName}'
|
||||||
else:
|
else:
|
||||||
@@ -131,7 +131,7 @@ class AnnotationLoaderMixin:
|
|||||||
TypedefNode.set('source', 'annotation_module')
|
TypedefNode.set('source', 'annotation_module')
|
||||||
TypedefNode.library_name = lib_name
|
TypedefNode.library_name = lib_name
|
||||||
TypedefNode.file = source_file
|
TypedefNode.file = source_file
|
||||||
self.SymbolTable[PublicName] = TypedefNode
|
self.SymbolTable.insert(PublicName, TypedefNode)
|
||||||
if lib_name and FullName != PublicName:
|
if lib_name and FullName != PublicName:
|
||||||
FullTypedef_node = CTypeInfo()
|
FullTypedef_node = CTypeInfo()
|
||||||
FullTypedef_node.Name = FullName
|
FullTypedef_node.Name = FullName
|
||||||
@@ -140,7 +140,7 @@ class AnnotationLoaderMixin:
|
|||||||
FullTypedef_node.set('source', 'annotation_module')
|
FullTypedef_node.set('source', 'annotation_module')
|
||||||
FullTypedef_node.library_name = lib_name
|
FullTypedef_node.library_name = lib_name
|
||||||
FullTypedef_node.file = source_file
|
FullTypedef_node.file = source_file
|
||||||
self.SymbolTable[FullName] = FullTypedef_node
|
self.SymbolTable.insert(FullName, FullTypedef_node)
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
@@ -208,14 +208,14 @@ class AnnotationLoaderMixin:
|
|||||||
if isinstance(base, ast.Name) and base.id == 'CType':
|
if isinstance(base, ast.Name) and base.id == 'CType':
|
||||||
# 这个类继承自 CType,是 typedef 别名
|
# 这个类继承自 CType,是 typedef 别名
|
||||||
# 更新符号表中的类型为 typedef
|
# 更新符号表中的类型为 typedef
|
||||||
if ClassName in self.SymbolTable:
|
if self.SymbolTable.has(ClassName):
|
||||||
TypedefNode = CTypeInfo()
|
TypedefNode = CTypeInfo()
|
||||||
TypedefNode.Name = ClassName
|
TypedefNode.Name = ClassName
|
||||||
TypedefNode.IsTypedef = True
|
TypedefNode.IsTypedef = True
|
||||||
TypedefNode.OriginalType = self.SymbolTable[ClassName].get('OriginalType', f'struct {ClassName}')
|
TypedefNode.OriginalType = self.SymbolTable[ClassName].get('OriginalType', f'struct {ClassName}')
|
||||||
TypedefNode.set('source', 'annotation_module')
|
TypedefNode.set('source', 'annotation_module')
|
||||||
TypedefNode.set('is_ctype_subclass', True)
|
TypedefNode.set('is_ctype_subclass', True)
|
||||||
self.SymbolTable[ClassName] = TypedefNode
|
self.SymbolTable.insert(ClassName, TypedefNode)
|
||||||
except Exception as _e:
|
except Exception as _e:
|
||||||
from lib.core.VLogger import get_logger as _vlog
|
from lib.core.VLogger import get_logger as _vlog
|
||||||
from lib.constants.config import mode as _ConfigMode
|
from lib.constants.config import mode as _ConfigMode
|
||||||
@@ -230,7 +230,7 @@ class AnnotationLoaderMixin:
|
|||||||
TypeInfo = self.SymbolTable[TypeName].copy()
|
TypeInfo = self.SymbolTable[TypeName].copy()
|
||||||
TypeInfo['source'] = 'annotation_module'
|
TypeInfo['source'] = 'annotation_module'
|
||||||
TypeInfo['original_name'] = TypeName
|
TypeInfo['original_name'] = TypeName
|
||||||
self.SymbolTable[FullName] = TypeInfo
|
self.SymbolTable.insert(FullName, TypeInfo)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
# 再次遍历 AST,查找注解文件中的 typedef 语句(AnnAssign with t.CTypedef)
|
# 再次遍历 AST,查找注解文件中的 typedef 语句(AnnAssign with t.CTypedef)
|
||||||
@@ -283,9 +283,9 @@ class AnnotationLoaderMixin:
|
|||||||
MemberNode.EnumName = TypePrefix
|
MemberNode.EnumName = TypePrefix
|
||||||
MemberNode.library_name = TypePrefix
|
MemberNode.library_name = TypePrefix
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.SymbolTable[TargetName] = MemberNode
|
self.SymbolTable.insert(TargetName, MemberNode)
|
||||||
self.SymbolTable[f"{TypePrefix}.{TargetName}"] = MemberNode
|
self.SymbolTable.insert(f"{TypePrefix}.{TargetName}", MemberNode)
|
||||||
self.SymbolTable[f"{TypePrefix}_{TargetName}"] = MemberNode
|
self.SymbolTable.insert(f"{TypePrefix}_{TargetName}", MemberNode)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(ModuleName, 'r', encoding='utf-8') as f:
|
with open(ModuleName, 'r', encoding='utf-8') as f:
|
||||||
@@ -315,13 +315,13 @@ class AnnotationLoaderMixin:
|
|||||||
for TargetName, original_name in typedef_annots:
|
for TargetName, original_name in typedef_annots:
|
||||||
# 检查原始类型是否在符号表中(带前缀或不带前缀)
|
# 检查原始类型是否在符号表中(带前缀或不带前缀)
|
||||||
orig_with_prefix = f'{TypePrefix}.{original_name}'
|
orig_with_prefix = f'{TypePrefix}.{original_name}'
|
||||||
if orig_with_prefix in self.SymbolTable:
|
if self.SymbolTable.has(orig_with_prefix):
|
||||||
# 添加带前缀的 typedef 别名
|
# 添加带前缀的 typedef 别名
|
||||||
FullTypedef_name = f'{TypePrefix}.{TargetName}'
|
FullTypedef_name = f'{TypePrefix}.{TargetName}'
|
||||||
TypedefNode = CTypeInfo()
|
TypedefNode = CTypeInfo()
|
||||||
TypedefNode.Name = FullTypedef_name
|
TypedefNode.Name = FullTypedef_name
|
||||||
TypedefNode.IsTypedef = True
|
TypedefNode.IsTypedef = True
|
||||||
orig_entry = self.SymbolTable.get(orig_with_prefix, {})
|
orig_entry = self.SymbolTable.lookup(orig_with_prefix)
|
||||||
orig_type_str = f'struct {original_name}'
|
orig_type_str = f'struct {original_name}'
|
||||||
if isinstance(orig_entry, dict):
|
if isinstance(orig_entry, dict):
|
||||||
if orig_entry.get('type') == 'typedef':
|
if orig_entry.get('type') == 'typedef':
|
||||||
@@ -335,7 +335,7 @@ class AnnotationLoaderMixin:
|
|||||||
TypedefNode.OriginalType = orig_type_str
|
TypedefNode.OriginalType = orig_type_str
|
||||||
TypedefNode.set('source', 'annotation_module')
|
TypedefNode.set('source', 'annotation_module')
|
||||||
TypedefNode.set('original_name', TargetName)
|
TypedefNode.set('original_name', TargetName)
|
||||||
self.SymbolTable[FullTypedef_name] = TypedefNode
|
self.SymbolTable.insert(FullTypedef_name, TypedefNode)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
self.AnnotationModules.add(lib_name)
|
self.AnnotationModules.add(lib_name)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class LlvmGeneratorMixin:
|
|||||||
sym_info = _CTypeInfo()
|
sym_info = _CTypeInfo()
|
||||||
sym_info.IsDefine = True
|
sym_info.IsDefine = True
|
||||||
sym_info.DefineValue = val
|
sym_info.DefineValue = val
|
||||||
self.SymbolTable[Node.target.id] = sym_info
|
self.SymbolTable.insert(Node.target.id, sym_info)
|
||||||
elif isinstance(Node, ast.Assign):
|
elif isinstance(Node, ast.Assign):
|
||||||
for target in Node.targets:
|
for target in Node.targets:
|
||||||
if isinstance(target, ast.Name):
|
if isinstance(target, ast.Name):
|
||||||
@@ -86,7 +86,7 @@ class LlvmGeneratorMixin:
|
|||||||
sym_info = _CTypeInfo()
|
sym_info = _CTypeInfo()
|
||||||
sym_info.IsDefine = True
|
sym_info.IsDefine = True
|
||||||
sym_info.DefineValue = val
|
sym_info.DefineValue = val
|
||||||
self.SymbolTable[target.id] = sym_info
|
self.SymbolTable.insert(target.id, sym_info)
|
||||||
|
|
||||||
# 预扫描所有顶层函数定义,填充 FunctionDefCache(不创建 LLVM 声明)
|
# 预扫描所有顶层函数定义,填充 FunctionDefCache(不创建 LLVM 声明)
|
||||||
# 这样类方法编译时遇到未声明的函数可以按需前向声明
|
# 这样类方法编译时遇到未声明的函数可以按需前向声明
|
||||||
@@ -287,8 +287,6 @@ class LlvmGeneratorMixin:
|
|||||||
self.VarScopes = [{}] # 全局作用域
|
self.VarScopes = [{}] # 全局作用域
|
||||||
|
|
||||||
# 预扫描 import 语句,注册别名,确保类型解析时能正确解析模块别名
|
# 预扫描 import 语句,注册别名,确保类型解析时能正确解析模块别名
|
||||||
if not getattr(self, '_ImportAliases', None):
|
|
||||||
self._ImportAliases = {}
|
|
||||||
if not getattr(self, '_ImportedModules', None):
|
if not getattr(self, '_ImportedModules', None):
|
||||||
self._ImportedModules = set()
|
self._ImportedModules = set()
|
||||||
for Node in ast.iter_child_nodes(Tree):
|
for Node in ast.iter_child_nodes(Tree):
|
||||||
@@ -299,14 +297,14 @@ class LlvmGeneratorMixin:
|
|||||||
continue
|
continue
|
||||||
self._ImportedModules.add(name)
|
self._ImportedModules.add(name)
|
||||||
if alias.asname:
|
if alias.asname:
|
||||||
self._ImportAliases[alias.asname] = name
|
self.SymbolTable.import_aliases[alias.asname] = name
|
||||||
elif isinstance(Node, ast.ImportFrom):
|
elif isinstance(Node, ast.ImportFrom):
|
||||||
module_name = Node.module
|
module_name = Node.module
|
||||||
if module_name and module_name not in ('c', 't'):
|
if module_name and module_name not in ('c', 't'):
|
||||||
self._ImportedModules.add(module_name)
|
self._ImportedModules.add(module_name)
|
||||||
for alias in Node.names:
|
for alias in Node.names:
|
||||||
if alias.asname:
|
if alias.asname:
|
||||||
self._ImportAliases[alias.asname] = f"{module_name}.{alias.name}"
|
self.SymbolTable.import_aliases[alias.asname] = f"{module_name}.{alias.name}"
|
||||||
|
|
||||||
for Node in ast.iter_child_nodes(Tree):
|
for Node in ast.iter_child_nodes(Tree):
|
||||||
if isinstance(Node, ast.ClassDef):
|
if isinstance(Node, ast.ClassDef):
|
||||||
@@ -373,7 +371,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.OriginalType = f'struct {ClassName}'
|
TypedefNode.OriginalType = f'struct {ClassName}'
|
||||||
TypedefNode.set('IsComplete', True)
|
TypedefNode.set('IsComplete', True)
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[TypedefKey] = TypedefNode
|
self.SymbolTable.insert(TypedefKey, TypedefNode)
|
||||||
|
|
||||||
for item in Node.body:
|
for item in Node.body:
|
||||||
if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
|
if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
|
||||||
@@ -414,18 +412,18 @@ class LlvmGeneratorMixin:
|
|||||||
StructNode.IsStruct = True
|
StructNode.IsStruct = True
|
||||||
StructNode.Members = members or {}
|
StructNode.Members = members or {}
|
||||||
StructNode.file = '<stdin>'
|
StructNode.file = '<stdin>'
|
||||||
if ClassName in self.SymbolTable:
|
if self.SymbolTable.has(ClassName):
|
||||||
existing = self.SymbolTable[ClassName]
|
existing = self.SymbolTable[ClassName]
|
||||||
if hasattr(existing, 'IsCpythonObject') and existing.IsCpythonObject:
|
if hasattr(existing, 'IsCpythonObject') and existing.IsCpythonObject:
|
||||||
StructNode.IsCpythonObject = True
|
StructNode.IsCpythonObject = True
|
||||||
self.SymbolTable[ClassName] = StructNode
|
self.SymbolTable.insert(ClassName, StructNode)
|
||||||
elif isinstance(Node, ast.FunctionDef):
|
elif isinstance(Node, ast.FunctionDef):
|
||||||
FuncName = Node.name
|
FuncName = Node.name
|
||||||
FuncNode = CTypeInfo()
|
FuncNode = CTypeInfo()
|
||||||
FuncNode.Name = FuncName
|
FuncNode.Name = FuncName
|
||||||
FuncNode.IsFunction = True
|
FuncNode.IsFunction = True
|
||||||
FuncNode.file = '<stdin>'
|
FuncNode.file = '<stdin>'
|
||||||
self.SymbolTable[FuncName] = FuncNode
|
self.SymbolTable.insert(FuncName, FuncNode)
|
||||||
elif isinstance(Node, ast.AnnAssign):
|
elif isinstance(Node, ast.AnnAssign):
|
||||||
if isinstance(Node.target, ast.Name):
|
if isinstance(Node.target, ast.Name):
|
||||||
VarName = Node.target.id
|
VarName = Node.target.id
|
||||||
@@ -447,7 +445,7 @@ class LlvmGeneratorMixin:
|
|||||||
if isinstance(Node.value, ast.Name):
|
if isinstance(Node.value, ast.Name):
|
||||||
OriginalType = Node.value.id
|
OriginalType = Node.value.id
|
||||||
if OriginalType in self.GeneratedTypes:
|
if OriginalType in self.GeneratedTypes:
|
||||||
if OriginalType in self.SymbolTable:
|
if self.SymbolTable.has(OriginalType):
|
||||||
OriginalInfo = self.SymbolTable[OriginalType]
|
OriginalInfo = self.SymbolTable[OriginalType]
|
||||||
if isinstance(OriginalInfo, dict):
|
if isinstance(OriginalInfo, dict):
|
||||||
actual_type = OriginalInfo.get('type', 'struct')
|
actual_type = OriginalInfo.get('type', 'struct')
|
||||||
@@ -468,7 +466,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.IsTypedef = True
|
TypedefNode.IsTypedef = True
|
||||||
TypedefNode.OriginalType = f'enum {OriginalType}'
|
TypedefNode.OriginalType = f'enum {OriginalType}'
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
elif actual_type == 'typedef':
|
elif actual_type == 'typedef':
|
||||||
TypedefNode = CTypeInfo()
|
TypedefNode = CTypeInfo()
|
||||||
TypedefNode.Name = VarName
|
TypedefNode.Name = VarName
|
||||||
@@ -481,7 +479,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.OriginalType = f'struct {OriginalType}'
|
TypedefNode.OriginalType = f'struct {OriginalType}'
|
||||||
TypedefNode.set('PendingTypedef', True)
|
TypedefNode.set('PendingTypedef', True)
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
else:
|
else:
|
||||||
TypedefNode = CTypeInfo()
|
TypedefNode = CTypeInfo()
|
||||||
TypedefNode.Name = VarName
|
TypedefNode.Name = VarName
|
||||||
@@ -489,11 +487,11 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.OriginalType = f'struct {OriginalType}'
|
TypedefNode.OriginalType = f'struct {OriginalType}'
|
||||||
TypedefNode.set('PendingTypedef', True)
|
TypedefNode.set('PendingTypedef', True)
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
self.GeneratedTypes.add(VarName)
|
self.GeneratedTypes.add(VarName)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if OriginalType in self.SymbolTable:
|
if self.SymbolTable.has(OriginalType):
|
||||||
OriginalInfo = self.SymbolTable[OriginalType]
|
OriginalInfo = self.SymbolTable[OriginalType]
|
||||||
if isinstance(OriginalInfo, dict):
|
if isinstance(OriginalInfo, dict):
|
||||||
actual_type = OriginalInfo.get('type', 'struct')
|
actual_type = OriginalInfo.get('type', 'struct')
|
||||||
@@ -520,7 +518,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.OriginalType = f'struct {OriginalType}'
|
TypedefNode.OriginalType = f'struct {OriginalType}'
|
||||||
TypedefNode.set('PendingTypedef', True)
|
TypedefNode.set('PendingTypedef', True)
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
self.GeneratedTypes.add(VarName)
|
self.GeneratedTypes.add(VarName)
|
||||||
if isinstance(OriginalInfo, dict):
|
if isinstance(OriginalInfo, dict):
|
||||||
OriginalInfo['skip_generation'] = True
|
OriginalInfo['skip_generation'] = True
|
||||||
@@ -532,7 +530,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.OriginalType = f'struct {OriginalType}'
|
TypedefNode.OriginalType = f'struct {OriginalType}'
|
||||||
TypedefNode.set('PendingTypedef', True)
|
TypedefNode.set('PendingTypedef', True)
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
self.GeneratedTypes.add(VarName)
|
self.GeneratedTypes.add(VarName)
|
||||||
if isinstance(OriginalInfo, dict):
|
if isinstance(OriginalInfo, dict):
|
||||||
OriginalInfo['skip_generation'] = True
|
OriginalInfo['skip_generation'] = True
|
||||||
@@ -544,7 +542,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.OriginalType = f'enum {OriginalType}'
|
TypedefNode.OriginalType = f'enum {OriginalType}'
|
||||||
TypedefNode.set('PendingTypedef', True)
|
TypedefNode.set('PendingTypedef', True)
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
self.GeneratedTypes.add(VarName)
|
self.GeneratedTypes.add(VarName)
|
||||||
if isinstance(OriginalInfo, dict):
|
if isinstance(OriginalInfo, dict):
|
||||||
OriginalInfo['skip_generation'] = True
|
OriginalInfo['skip_generation'] = True
|
||||||
@@ -558,7 +556,7 @@ class LlvmGeneratorMixin:
|
|||||||
TypedefNode.IsTypedef = True
|
TypedefNode.IsTypedef = True
|
||||||
TypedefNode.OriginalType = CName
|
TypedefNode.OriginalType = CName
|
||||||
TypedefNode.file = '<stdin>'
|
TypedefNode.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = TypedefNode
|
self.SymbolTable.insert(VarName, TypedefNode)
|
||||||
self.GeneratedTypes.add(VarName)
|
self.GeneratedTypes.add(VarName)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -574,7 +572,7 @@ class LlvmGeneratorMixin:
|
|||||||
var_node.IsVariable = True
|
var_node.IsVariable = True
|
||||||
var_node.PtrCount = 1 if IsPtr else 0
|
var_node.PtrCount = 1 if IsPtr else 0
|
||||||
var_node.file = '<stdin>'
|
var_node.file = '<stdin>'
|
||||||
self.SymbolTable[VarName] = var_node
|
self.SymbolTable.insert(VarName, var_node)
|
||||||
|
|
||||||
self.LlvmGen = LlvmCodeGenerator(
|
self.LlvmGen = LlvmCodeGenerator(
|
||||||
triple=getattr(self, 'triple', None),
|
triple=getattr(self, 'triple', None),
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ class PythonParserMixin:
|
|||||||
EnumNode.Name = ClassName
|
EnumNode.Name = ClassName
|
||||||
EnumNode.IsEnum = True
|
EnumNode.IsEnum = True
|
||||||
EnumNode.set('file', '<stdin>')
|
EnumNode.set('file', '<stdin>')
|
||||||
self.SymbolTable[ClassName] = EnumNode
|
self.SymbolTable.insert(ClassName, EnumNode)
|
||||||
|
|
||||||
# 注册 enum 成员
|
# 注册 enum 成员
|
||||||
for item in node.body:
|
for item in node.body:
|
||||||
@@ -341,9 +341,9 @@ class PythonParserMixin:
|
|||||||
MemberNode.EnumName = ClassName
|
MemberNode.EnumName = ClassName
|
||||||
MemberNode.library_name = None
|
MemberNode.library_name = None
|
||||||
MemberNode.IsEnumMember = True
|
MemberNode.IsEnumMember = True
|
||||||
self.SymbolTable[MemberName] = MemberNode
|
self.SymbolTable.insert(MemberName, MemberNode)
|
||||||
self.SymbolTable[f"{ClassName}.{MemberName}"] = MemberNode
|
self.SymbolTable.insert(f"{ClassName}.{MemberName}", MemberNode)
|
||||||
self.SymbolTable[f"{ClassName}_{MemberName}"] = MemberNode
|
self.SymbolTable.insert(f"{ClassName}_{MemberName}", MemberNode)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -397,14 +397,14 @@ class PythonParserMixin:
|
|||||||
StructNode.set('file', '<stdin>')
|
StructNode.set('file', '<stdin>')
|
||||||
StructNode.set('IsAnonymous', IsAnonymous)
|
StructNode.set('IsAnonymous', IsAnonymous)
|
||||||
StructNode.set('IsCpythonObject', IsCpythonObject)
|
StructNode.set('IsCpythonObject', IsCpythonObject)
|
||||||
self.SymbolTable[ClassName] = StructNode
|
self.SymbolTable.insert(ClassName, StructNode)
|
||||||
elif isinstance(node, ast.FunctionDef):
|
elif isinstance(node, ast.FunctionDef):
|
||||||
FuncName = node.name
|
FuncName = node.name
|
||||||
FuncNode = CTypeInfo()
|
FuncNode = CTypeInfo()
|
||||||
FuncNode.Name = FuncName
|
FuncNode.Name = FuncName
|
||||||
FuncNode.IsFunction = True
|
FuncNode.IsFunction = True
|
||||||
FuncNode.set('file', '<stdin>')
|
FuncNode.set('file', '<stdin>')
|
||||||
self.SymbolTable[FuncName] = FuncNode
|
self.SymbolTable.insert(FuncName, FuncNode)
|
||||||
elif isinstance(node, ast.AnnAssign):
|
elif isinstance(node, ast.AnnAssign):
|
||||||
if isinstance(node.target, ast.Name):
|
if isinstance(node.target, ast.Name):
|
||||||
VarName = node.target.id
|
VarName = node.target.id
|
||||||
@@ -443,7 +443,7 @@ class PythonParserMixin:
|
|||||||
var_node.IsVariable = True
|
var_node.IsVariable = True
|
||||||
var_node.set('IsPtr', IsPtr)
|
var_node.set('IsPtr', IsPtr)
|
||||||
var_node.set('file', '<stdin>')
|
var_node.set('file', '<stdin>')
|
||||||
self.SymbolTable[VarName] = var_node
|
self.SymbolTable.insert(VarName, var_node)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'Warning: Failed to parse Python file {FilePath}: {e}')
|
print(f'Warning: Failed to parse Python file {FilePath}: {e}')
|
||||||
|
|
||||||
|
|||||||
704
lib/core/TypeAnnotationResolver.py
Normal file
704
lib/core/TypeAnnotationResolver.py
Normal file
@@ -0,0 +1,704 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
import ast
|
||||||
|
from lib.core.Handles.HandlesBase import CTypeInfo, BuiltinTypeMap, CTypeHelper
|
||||||
|
|
||||||
|
|
||||||
|
class TypeAnnotationResolver:
|
||||||
|
"""从 AST 节点解析类型注解,独立于 CTypeInfo 数据模型。"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_type_name(TypeName: str) -> CTypeInfo:
|
||||||
|
"""从简单类型名构造 CTypeInfo(不经过 FromStr 字符串解析)"""
|
||||||
|
# Handle pointer types like 'CUInt32T *', 'void *', etc.
|
||||||
|
ptr_count = 0
|
||||||
|
base_name = TypeName
|
||||||
|
while base_name.endswith(' *') or base_name.endswith('*'):
|
||||||
|
ptr_count += 1
|
||||||
|
base_name = base_name.rstrip(' *').rstrip()
|
||||||
|
|
||||||
|
entry = BuiltinTypeMap.Get(base_name)
|
||||||
|
if entry:
|
||||||
|
TypeClass, base_ptr = entry
|
||||||
|
info = CTypeInfo()
|
||||||
|
info.BaseType = TypeClass
|
||||||
|
info.PtrCount = base_ptr + ptr_count
|
||||||
|
return info
|
||||||
|
# Handle LLVM primitive type names (e.g., 'i64', 'double' from generic type inference)
|
||||||
|
llvm_map = CTypeInfo._get_llvm_primitive_map()
|
||||||
|
llvm_entry = llvm_map.get(base_name)
|
||||||
|
if llvm_entry:
|
||||||
|
TypeClass, base_ptr = llvm_entry
|
||||||
|
info = CTypeInfo()
|
||||||
|
info.BaseType = TypeClass
|
||||||
|
info.PtrCount = base_ptr + ptr_count
|
||||||
|
return info
|
||||||
|
# Fallback with pointer count
|
||||||
|
info = CTypeInfo.CreateFromTypeName(TypeName)
|
||||||
|
if ptr_count > 0:
|
||||||
|
info.PtrCount = ptr_count
|
||||||
|
return info
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def try_eval_const_expr(node, SymbolTable):
|
||||||
|
from lib.core.ConstEvaluator import ConstEvaluator
|
||||||
|
return ConstEvaluator.eval_with_symtab(node, SymbolTable)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_node(Node: ast.AST, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""从 AST 节点解析 CTypeInfo
|
||||||
|
|
||||||
|
Args:
|
||||||
|
Node: AST 节点(如 ast.Name, ast.Attribute 等)
|
||||||
|
SymbolTable: 符号表字典
|
||||||
|
"""
|
||||||
|
if isinstance(Node, (ast.Constant, ast.Str)):
|
||||||
|
return TypeAnnotationResolver._from_node_constant(Node, SymbolTable)
|
||||||
|
if isinstance(Node, ast.Name):
|
||||||
|
return TypeAnnotationResolver._from_node_name(Node, SymbolTable)
|
||||||
|
if isinstance(Node, ast.Call):
|
||||||
|
return TypeAnnotationResolver._from_node_call(Node, SymbolTable)
|
||||||
|
if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr):
|
||||||
|
return TypeAnnotationResolver._from_node_binop(Node, SymbolTable)
|
||||||
|
if isinstance(Node, ast.Subscript):
|
||||||
|
return TypeAnnotationResolver._from_node_subscript(Node, SymbolTable)
|
||||||
|
if isinstance(Node, ast.Attribute):
|
||||||
|
return TypeAnnotationResolver._from_node_attribute(Node, SymbolTable)
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_node_constant(Node: ast.AST, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""处理 ast.Constant / ast.Str 节点"""
|
||||||
|
if isinstance(Node, ast.Constant):
|
||||||
|
TypeName = Node.value
|
||||||
|
else:
|
||||||
|
TypeName = Node.s
|
||||||
|
return TypeAnnotationResolver.from_type_name(TypeName)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_node_name(Node: ast.Name, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""处理 ast.Name 节点"""
|
||||||
|
from lib.includes import t
|
||||||
|
|
||||||
|
TypeName = Node.id
|
||||||
|
TypeObj = CTypeHelper.GetTModuleCType(TypeName)
|
||||||
|
if TypeObj is None:
|
||||||
|
TypeObj = getattr(t, TypeName, None)
|
||||||
|
if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType) and TypeObj is not t.CType:
|
||||||
|
if TypeObj == t.CPtr:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.PtrCount = 1
|
||||||
|
Result.BaseType = t.CVoid()
|
||||||
|
return Result
|
||||||
|
if TypeObj == t.State:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsState = True
|
||||||
|
Result.BaseType = t.CVoid()
|
||||||
|
return Result
|
||||||
|
Inst = TypeObj()
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = TypeObj
|
||||||
|
if hasattr(Inst, 'CName') and Inst.CName:
|
||||||
|
Result.Name = Inst.CName
|
||||||
|
if hasattr(Inst, 'IsSigned'):
|
||||||
|
Result.IsSigned = Inst.IsSigned
|
||||||
|
return Result
|
||||||
|
if TypeName in SymbolTable:
|
||||||
|
Entry = SymbolTable[TypeName]
|
||||||
|
if Entry:
|
||||||
|
if isinstance(Entry, CTypeInfo):
|
||||||
|
if Entry.IsTypedef:
|
||||||
|
if Entry.BaseType and (not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0):
|
||||||
|
Result = Entry.Copy()
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
if Entry.OriginalType:
|
||||||
|
if isinstance(Entry.OriginalType, CTypeInfo) and Entry.OriginalType.IsFuncPtr:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsFuncPtr = True
|
||||||
|
Result.FuncPtrReturn = Entry.OriginalType.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
|
||||||
|
Result.FuncPtrParams = list(Entry.OriginalType.FuncPtrParams) if Entry.OriginalType.FuncPtrParams else []
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
elif isinstance(Entry.OriginalType, CTypeInfo):
|
||||||
|
Resolved = Entry.OriginalType.Copy()
|
||||||
|
elif isinstance(Entry.OriginalType, str) and Entry.OriginalType == 'Callable':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsFuncPtr = True
|
||||||
|
Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
|
||||||
|
Result.FuncPtrParams = []
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
elif isinstance(Entry.OriginalType, str):
|
||||||
|
Resolved = TypeAnnotationResolver.from_type_name(Entry.OriginalType)
|
||||||
|
else:
|
||||||
|
Resolved = Entry.OriginalType
|
||||||
|
Resolved.IsTypedef = True
|
||||||
|
Resolved.Name = TypeName
|
||||||
|
return Resolved
|
||||||
|
TypeEntry = BuiltinTypeMap.Get(TypeName)
|
||||||
|
if TypeEntry:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = TypeEntry[0]()
|
||||||
|
Result.PtrCount = TypeEntry[1]
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
return Entry
|
||||||
|
if Entry.IsEnum:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.IsEnum = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
if Entry.IsExceptionClass:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.IsExceptionClass = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
if Entry.BaseType is None and (Entry.IsStruct or Entry.Name):
|
||||||
|
Entry.BaseType = t.CStruct(name=TypeName)
|
||||||
|
Entry.IsStruct = True
|
||||||
|
return Entry
|
||||||
|
elif isinstance(Entry, dict):
|
||||||
|
if Entry.get('type') == 'typedef':
|
||||||
|
OriginalType = Entry.get('OriginalType', '')
|
||||||
|
if OriginalType:
|
||||||
|
if OriginalType == 'Callable':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsFuncPtr = True
|
||||||
|
Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
|
||||||
|
Result.FuncPtrParams = []
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
Resolved = TypeAnnotationResolver.from_type_name(OriginalType)
|
||||||
|
Resolved.IsTypedef = True
|
||||||
|
Resolved.Name = TypeName
|
||||||
|
return Resolved
|
||||||
|
TypeEntry = BuiltinTypeMap.Get(TypeName)
|
||||||
|
if TypeEntry:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = TypeEntry[0]()
|
||||||
|
Result.PtrCount = TypeEntry[1]
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t._CTypedef(TypeName)
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
# 特殊处理 str 类型,它应该是 char*(指针)
|
||||||
|
if TypeName in ('str', 'bytes'):
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CChar()
|
||||||
|
Result.PtrCount = 1
|
||||||
|
return Result
|
||||||
|
if TypeName == 'irq_handler_t':
|
||||||
|
pass
|
||||||
|
return TypeAnnotationResolver.from_type_name(TypeName)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_node_call(Node: ast.Call, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""处理 ast.Call 节点"""
|
||||||
|
from lib.includes import t
|
||||||
|
|
||||||
|
if isinstance(Node.func, ast.Name) and Node.func.id == 'callable':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsFuncPtr = True
|
||||||
|
Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
|
||||||
|
Result.FuncPtrParams = []
|
||||||
|
try:
|
||||||
|
if len(Node.args) > 0:
|
||||||
|
RetInfo = TypeAnnotationResolver.from_node(Node.args[0], SymbolTable)
|
||||||
|
if RetInfo:
|
||||||
|
Result.FuncPtrReturn = RetInfo
|
||||||
|
for kw in Node.keywords:
|
||||||
|
ParamInfo = TypeAnnotationResolver.from_node(kw.value, SymbolTable)
|
||||||
|
if ParamInfo:
|
||||||
|
Result.FuncPtrParams.append((kw.arg or '', ParamInfo))
|
||||||
|
except Exception as _e:
|
||||||
|
if __import__('lib.constants.config', fromlist=['mode']).mode == "strict":
|
||||||
|
import warnings; warnings.warn(f"异常被忽略: {_e}")
|
||||||
|
return Result
|
||||||
|
if isinstance(Node.func, ast.Attribute):
|
||||||
|
if isinstance(Node.func.value, ast.Name) and Node.func.value.id == 't':
|
||||||
|
if Node.func.attr == 'Bit' and len(Node.args) > 0:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.IsBitField = True
|
||||||
|
if isinstance(Node.args[0], ast.Constant) and isinstance(Node.args[0].value, int):
|
||||||
|
Result.BitWidth = Node.args[0].value
|
||||||
|
else:
|
||||||
|
Result.BitWidth = 1
|
||||||
|
return Result
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_node_binop(Node: ast.BinOp, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""处理 ast.BinOp (BitOr) 节点"""
|
||||||
|
from lib.includes import t
|
||||||
|
|
||||||
|
LeftInfo = TypeAnnotationResolver.from_node(Node.left, SymbolTable)
|
||||||
|
RightInfo = TypeAnnotationResolver.from_node(Node.right, SymbolTable)
|
||||||
|
|
||||||
|
if LeftInfo.IsState or RightInfo.IsState:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsState = True
|
||||||
|
NonStateInfo = LeftInfo if not LeftInfo.IsState else RightInfo
|
||||||
|
StateInfo = LeftInfo if LeftInfo.IsState else RightInfo
|
||||||
|
if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0):
|
||||||
|
Result.BaseType = NonStateInfo.BaseType
|
||||||
|
elif NonStateInfo.IsTypedef and NonStateInfo.Name:
|
||||||
|
if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0):
|
||||||
|
Result.BaseType = NonStateInfo.BaseType
|
||||||
|
Result.PtrCount = NonStateInfo.PtrCount
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = NonStateInfo.Name
|
||||||
|
if NonStateInfo.OriginalType:
|
||||||
|
Result.OriginalType = NonStateInfo.OriginalType
|
||||||
|
else:
|
||||||
|
Result.BaseType = t.CStruct(name=NonStateInfo.Name)
|
||||||
|
Result.IsStruct = True
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = NonStateInfo.Name
|
||||||
|
if NonStateInfo.OriginalType:
|
||||||
|
Result.OriginalType = NonStateInfo.OriginalType
|
||||||
|
else:
|
||||||
|
Result.BaseType = t.CVoid()
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
if not Result.Storage:
|
||||||
|
Result.Storage = t.CExport()
|
||||||
|
if LeftInfo.Storage and not isinstance(LeftInfo.Storage, t.CExport):
|
||||||
|
Result.Storage = LeftInfo.Storage
|
||||||
|
elif RightInfo.Storage and not isinstance(RightInfo.Storage, t.CExport):
|
||||||
|
Result.Storage = RightInfo.Storage
|
||||||
|
if LeftInfo.DataConst or RightInfo.DataConst:
|
||||||
|
Result.DataConst = True
|
||||||
|
if LeftInfo.VarConst or RightInfo.VarConst:
|
||||||
|
Result.VarConst = True
|
||||||
|
return Result
|
||||||
|
|
||||||
|
if LeftInfo.IsPtr or RightInfo.IsPtr:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
NonPtrInfo = LeftInfo if not LeftInfo.IsPtr else RightInfo
|
||||||
|
PtrInfo = RightInfo if RightInfo.IsPtr else LeftInfo
|
||||||
|
if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0):
|
||||||
|
Result.BaseType = NonPtrInfo.BaseType
|
||||||
|
elif NonPtrInfo.IsTypedef and NonPtrInfo.Name:
|
||||||
|
if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0):
|
||||||
|
Result.BaseType = NonPtrInfo.BaseType
|
||||||
|
Result.IsTypedef = True
|
||||||
|
Result.Name = NonPtrInfo.Name
|
||||||
|
if NonPtrInfo.OriginalType:
|
||||||
|
Result.OriginalType = NonPtrInfo.OriginalType
|
||||||
|
else:
|
||||||
|
Result.BaseType = t.CStruct(name=NonPtrInfo.Name)
|
||||||
|
Result.IsStruct = True
|
||||||
|
elif PtrInfo.BaseType and (not isinstance(PtrInfo.BaseType, (t._CTypedef,)) or PtrInfo.PtrCount > 0):
|
||||||
|
Result.BaseType = PtrInfo.BaseType
|
||||||
|
else:
|
||||||
|
Result.BaseType = t.CUnsignedChar()
|
||||||
|
if LeftInfo.DataConst or RightInfo.DataConst:
|
||||||
|
Result.DataConst = True
|
||||||
|
if LeftInfo.VarConst or RightInfo.VarConst:
|
||||||
|
Result.VarConst = True
|
||||||
|
if LeftInfo.DataVolatile or RightInfo.DataVolatile:
|
||||||
|
Result.DataVolatile = True
|
||||||
|
if LeftInfo.VarVolatile or RightInfo.VarVolatile:
|
||||||
|
Result.VarVolatile = True
|
||||||
|
if LeftInfo.Storage:
|
||||||
|
Result.Storage = LeftInfo.Storage
|
||||||
|
elif RightInfo.Storage:
|
||||||
|
Result.Storage = RightInfo.Storage
|
||||||
|
return Result
|
||||||
|
|
||||||
|
if LeftInfo.DataConst or RightInfo.DataConst:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
BaseTypeSide = LeftInfo if not LeftInfo.DataConst else RightInfo
|
||||||
|
QualSide = LeftInfo if LeftInfo.DataConst else RightInfo
|
||||||
|
Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType
|
||||||
|
if not Result.BaseType:
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.DataConst = True
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
if LeftInfo.VarConst or RightInfo.VarConst:
|
||||||
|
Result.VarConst = True
|
||||||
|
if LeftInfo.DataVolatile or RightInfo.DataVolatile:
|
||||||
|
Result.DataVolatile = True
|
||||||
|
if LeftInfo.Storage:
|
||||||
|
Result.Storage = LeftInfo.Storage
|
||||||
|
elif RightInfo.Storage:
|
||||||
|
Result.Storage = RightInfo.Storage
|
||||||
|
return Result
|
||||||
|
|
||||||
|
if LeftInfo.DataVolatile or RightInfo.DataVolatile:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
BaseTypeSide = LeftInfo if not LeftInfo.DataVolatile else RightInfo
|
||||||
|
QualSide = LeftInfo if LeftInfo.DataVolatile else RightInfo
|
||||||
|
Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType
|
||||||
|
if not Result.BaseType:
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.DataVolatile = True
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
if LeftInfo.VarConst or RightInfo.VarConst:
|
||||||
|
Result.VarConst = True
|
||||||
|
if LeftInfo.Storage:
|
||||||
|
Result.Storage = LeftInfo.Storage
|
||||||
|
elif RightInfo.Storage:
|
||||||
|
Result.Storage = RightInfo.Storage
|
||||||
|
return Result
|
||||||
|
|
||||||
|
if LeftInfo.Storage or RightInfo.Storage:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
BaseTypeSide = LeftInfo if not LeftInfo.Storage else RightInfo
|
||||||
|
StorageSide = LeftInfo if LeftInfo.Storage else RightInfo
|
||||||
|
if BaseTypeSide.IsState or StorageSide.IsState:
|
||||||
|
Result.IsState = True
|
||||||
|
Result.BaseType = t.CVoid()
|
||||||
|
Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage
|
||||||
|
return Result
|
||||||
|
Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else StorageSide.BaseType
|
||||||
|
if not Result.BaseType:
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
if LeftInfo.DataConst or RightInfo.DataConst:
|
||||||
|
Result.DataConst = True
|
||||||
|
if LeftInfo.VarConst or RightInfo.VarConst:
|
||||||
|
Result.VarConst = True
|
||||||
|
return Result
|
||||||
|
|
||||||
|
# 检查是否有位域类型 (t.Bit)
|
||||||
|
if LeftInfo.IsBitField:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else t.CInt()
|
||||||
|
Result.IsBitField = True
|
||||||
|
Result.BitWidth = LeftInfo.BitWidth
|
||||||
|
return Result
|
||||||
|
if RightInfo.IsBitField:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else t.CInt()
|
||||||
|
Result.IsBitField = True
|
||||||
|
Result.BitWidth = RightInfo.BitWidth
|
||||||
|
return Result
|
||||||
|
|
||||||
|
# 处理字节序类型 (t.BigEndian, t.LittleEndian)
|
||||||
|
if LeftInfo.ByteOrder:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else t.CInt()
|
||||||
|
Result.ByteOrder = LeftInfo.ByteOrder
|
||||||
|
return Result
|
||||||
|
if RightInfo.ByteOrder:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else t.CInt()
|
||||||
|
Result.ByteOrder = RightInfo.ByteOrder
|
||||||
|
return Result
|
||||||
|
|
||||||
|
if LeftInfo.IsFuncPtr or RightInfo.IsFuncPtr:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
FuncPtrSide = LeftInfo if LeftInfo.IsFuncPtr else RightInfo
|
||||||
|
Result.IsFuncPtr = True
|
||||||
|
Result.FuncPtrParams = list(FuncPtrSide.FuncPtrParams)
|
||||||
|
Result.FuncPtrReturn = FuncPtrSide.FuncPtrReturn
|
||||||
|
if LeftInfo.Storage:
|
||||||
|
Result.Storage = LeftInfo.Storage
|
||||||
|
elif RightInfo.Storage:
|
||||||
|
Result.Storage = RightInfo.Storage
|
||||||
|
return Result
|
||||||
|
|
||||||
|
if LeftInfo.IsTypedef and RightInfo.BaseType:
|
||||||
|
if LeftInfo.BaseType and (not isinstance(LeftInfo.BaseType, (t._CTypedef,)) or LeftInfo.PtrCount > 0):
|
||||||
|
Result = LeftInfo.Copy()
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
if RightInfo.Storage:
|
||||||
|
Result.Storage = RightInfo.Storage
|
||||||
|
return Result
|
||||||
|
return RightInfo
|
||||||
|
if RightInfo.IsTypedef and LeftInfo.BaseType:
|
||||||
|
if RightInfo.BaseType and (not isinstance(RightInfo.BaseType, (t._CTypedef,)) or RightInfo.PtrCount > 0):
|
||||||
|
Result = RightInfo.Copy()
|
||||||
|
Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
|
||||||
|
if LeftInfo.Storage:
|
||||||
|
Result.Storage = LeftInfo.Storage
|
||||||
|
return Result
|
||||||
|
return LeftInfo
|
||||||
|
|
||||||
|
if LeftInfo.BaseType:
|
||||||
|
return LeftInfo
|
||||||
|
elif RightInfo.BaseType:
|
||||||
|
return RightInfo
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_node_subscript(Node: ast.Subscript, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""处理 ast.Subscript 节点"""
|
||||||
|
from lib.includes import t
|
||||||
|
|
||||||
|
base = Node.value
|
||||||
|
if isinstance(base, ast.Attribute):
|
||||||
|
if isinstance(base.value, ast.Name) and base.value.id == 't' and base.attr == 'Bit':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.IsBitField = True
|
||||||
|
if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int):
|
||||||
|
Result.BitWidth = Node.slice.value
|
||||||
|
else:
|
||||||
|
Result.BitWidth = 1
|
||||||
|
return Result
|
||||||
|
if isinstance(base, ast.Name) and base.id == 'list':
|
||||||
|
slice_node = Node.slice
|
||||||
|
elts = []
|
||||||
|
if isinstance(slice_node, ast.Tuple):
|
||||||
|
elts = slice_node.elts
|
||||||
|
elif isinstance(slice_node, (ast.Attribute, ast.Name, ast.Subscript)):
|
||||||
|
elts = [slice_node]
|
||||||
|
if elts:
|
||||||
|
ElemInfo = TypeAnnotationResolver.from_node(elts[0], SymbolTable)
|
||||||
|
if ElemInfo and ElemInfo.BaseType:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = ElemInfo.BaseType
|
||||||
|
Result.PtrCount = ElemInfo.PtrCount
|
||||||
|
Result.ArrayDims = list(ElemInfo.ArrayDims)
|
||||||
|
if len(elts) >= 2:
|
||||||
|
count_val = TypeAnnotationResolver.try_eval_const_expr(elts[1], SymbolTable)
|
||||||
|
if count_val is not None and isinstance(count_val, int) and count_val > 0:
|
||||||
|
Result.ArrayDims.insert(0, str(count_val))
|
||||||
|
else:
|
||||||
|
Result.PtrCount += 1
|
||||||
|
if ElemInfo.IsPtr and not ElemInfo.ArrayDims:
|
||||||
|
Result.PtrCount = max(Result.PtrCount, 1)
|
||||||
|
return Result
|
||||||
|
if isinstance(base, ast.Attribute):
|
||||||
|
parts = []
|
||||||
|
current = base
|
||||||
|
while isinstance(current, ast.Attribute):
|
||||||
|
parts.insert(0, current.attr)
|
||||||
|
current = current.value
|
||||||
|
if isinstance(current, ast.Name):
|
||||||
|
parts.insert(0, current.id)
|
||||||
|
if parts and parts[0] == 't' and parts[-1] == t.CPtr.__name__:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CVoid()
|
||||||
|
Result.PtrCount = 1
|
||||||
|
slice_node = Node.slice
|
||||||
|
if isinstance(slice_node, ast.Subscript):
|
||||||
|
InnerInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable)
|
||||||
|
if InnerInfo:
|
||||||
|
if InnerInfo.PtrCount > 0:
|
||||||
|
Result.PtrCount += InnerInfo.PtrCount
|
||||||
|
if InnerInfo.BaseType and not isinstance(InnerInfo.BaseType, t.CVoid):
|
||||||
|
Result.BaseType = InnerInfo.BaseType
|
||||||
|
elif isinstance(slice_node, ast.Attribute):
|
||||||
|
SliceInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable)
|
||||||
|
if SliceInfo:
|
||||||
|
if SliceInfo.IsPtr:
|
||||||
|
Result.PtrCount += SliceInfo.PtrCount
|
||||||
|
elif SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
|
||||||
|
Result.BaseType = SliceInfo.BaseType
|
||||||
|
elif isinstance(slice_node, ast.Name):
|
||||||
|
SliceType = getattr(t, slice_node.id, None)
|
||||||
|
if SliceType == t.CPtr:
|
||||||
|
Result.PtrCount += 1
|
||||||
|
else:
|
||||||
|
SliceInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable)
|
||||||
|
if SliceInfo and SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
|
||||||
|
Result.BaseType = SliceInfo.BaseType
|
||||||
|
return Result
|
||||||
|
if parts and parts[0] == 't' and parts[-1] == 'Callable':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsFuncPtr = True
|
||||||
|
slice_node = Node.slice
|
||||||
|
if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2:
|
||||||
|
params_list = slice_node.elts[0]
|
||||||
|
return_node = slice_node.elts[1]
|
||||||
|
ParamTypes = []
|
||||||
|
if isinstance(params_list, ast.List):
|
||||||
|
for elt in params_list.elts:
|
||||||
|
ParamTypeInfo = TypeAnnotationResolver.from_node(elt, SymbolTable)
|
||||||
|
if ParamTypeInfo:
|
||||||
|
ParamTypes.append(('', ParamTypeInfo))
|
||||||
|
if not ParamTypes:
|
||||||
|
ParamTypes.append(('', TypeAnnotationResolver.from_type_name('void')))
|
||||||
|
Result.FuncPtrParams = ParamTypes
|
||||||
|
ReturnTypeInfo = TypeAnnotationResolver.from_node(return_node, SymbolTable)
|
||||||
|
Result.FuncPtrReturn = ReturnTypeInfo if ReturnTypeInfo else CTypeInfo.VoidTypeInfo()
|
||||||
|
return Result
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_node_attribute(Node: ast.Attribute, SymbolTable: dict) -> CTypeInfo:
|
||||||
|
"""处理 ast.Attribute 节点"""
|
||||||
|
from lib.includes import t
|
||||||
|
|
||||||
|
ModuleParts = []
|
||||||
|
Current = Node
|
||||||
|
while isinstance(Current, ast.Attribute):
|
||||||
|
ModuleParts.insert(0, Current.attr)
|
||||||
|
Current = Current.value
|
||||||
|
|
||||||
|
if isinstance(Current, ast.Name):
|
||||||
|
ModuleParts.insert(0, Current.id)
|
||||||
|
|
||||||
|
if len(ModuleParts) >= 2:
|
||||||
|
TypeName = ModuleParts[-1]
|
||||||
|
ModulePath = '.'.join(ModuleParts[:-1])
|
||||||
|
elif len(ModuleParts) == 1:
|
||||||
|
TypeName = ModuleParts[0]
|
||||||
|
ModulePath = None
|
||||||
|
else:
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
# 解析 import 别名: 如 import vpsdk.window as window -> window -> vpsdk.window
|
||||||
|
if ModulePath:
|
||||||
|
resolved = False
|
||||||
|
import_aliases = SymbolTable.import_aliases
|
||||||
|
if ModulePath in import_aliases:
|
||||||
|
ModulePath = import_aliases[ModulePath]
|
||||||
|
resolved = True
|
||||||
|
if not resolved and ModulePath in SymbolTable:
|
||||||
|
entry = SymbolTable[ModulePath]
|
||||||
|
if isinstance(entry, CTypeInfo) and entry.IsModuleAlias:
|
||||||
|
resolved_name = entry.ResolvedModule
|
||||||
|
if resolved_name:
|
||||||
|
ModulePath = resolved_name
|
||||||
|
|
||||||
|
if ModulePath == 't' or (ModulePath and ModulePath.startswith('t.')):
|
||||||
|
TypeClass = CTypeHelper.GetTModuleCType(TypeName)
|
||||||
|
if TypeClass is None:
|
||||||
|
TypeClass = getattr(t, TypeName, None)
|
||||||
|
if TypeClass is not None and TypeClass.HasPosition(t.CType.POINTER):
|
||||||
|
Info = CTypeInfo()
|
||||||
|
Info.PtrCount = 1
|
||||||
|
if TypeClass == t.CArrayPtr:
|
||||||
|
Info.IsArrayPtr = True
|
||||||
|
Info.BaseType = t.CVoid
|
||||||
|
return Info
|
||||||
|
if TypeClass is not None and TypeClass.IsStorageClass():
|
||||||
|
Info = CTypeInfo()
|
||||||
|
Info.Storage = TypeClass()
|
||||||
|
if TypeClass == t.State:
|
||||||
|
Info.IsState = True
|
||||||
|
Info.BaseType = t.CVoid()
|
||||||
|
return Info
|
||||||
|
if TypeClass is not None and TypeClass.IsTypeQualifier():
|
||||||
|
Info = CTypeInfo()
|
||||||
|
if TypeClass == t.CConst:
|
||||||
|
Info.DataConst = True
|
||||||
|
elif TypeClass == t.CVolatile:
|
||||||
|
Info.DataVolatile = True
|
||||||
|
return Info
|
||||||
|
if (TypeClass is not None
|
||||||
|
and isinstance(TypeClass, type)
|
||||||
|
and issubclass(TypeClass, t.CType)
|
||||||
|
and TypeClass is not t.CType
|
||||||
|
and TypeClass.HasPosition(t.CType.BASE)):
|
||||||
|
if TypeClass == t.State:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.IsState = True
|
||||||
|
Result.BaseType = t.CVoid()
|
||||||
|
return Result
|
||||||
|
Inst = TypeClass()
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = TypeClass
|
||||||
|
if hasattr(Inst, 'CName') and Inst.CName:
|
||||||
|
Result.Name = Inst.CName
|
||||||
|
if hasattr(Inst, 'IsSigned'):
|
||||||
|
Result.IsSigned = Inst.IsSigned
|
||||||
|
return Result
|
||||||
|
CNAME = CTypeHelper.GetCName(TypeName)
|
||||||
|
if CNAME:
|
||||||
|
return TypeAnnotationResolver.from_type_name(CNAME)
|
||||||
|
|
||||||
|
# 处理字节序类型
|
||||||
|
if TypeName == 'BigEndian':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.ByteOrder = 'big'
|
||||||
|
return Result
|
||||||
|
if TypeName == 'LittleEndian':
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.ByteOrder = 'little'
|
||||||
|
return Result
|
||||||
|
|
||||||
|
FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName
|
||||||
|
|
||||||
|
if TypeName in SymbolTable:
|
||||||
|
Entry = SymbolTable[TypeName]
|
||||||
|
if Entry and Entry.IsTypedef:
|
||||||
|
Resolved = Entry.Copy()
|
||||||
|
if Resolved.BaseType is None:
|
||||||
|
Resolved.BaseType = t._CTypedef(TypeName)
|
||||||
|
return Resolved
|
||||||
|
if Entry and Entry.IsEnum:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.IsEnum = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
if Entry and Entry.IsExceptionClass:
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t.CInt()
|
||||||
|
Result.IsExceptionClass = True
|
||||||
|
Result.Name = TypeName
|
||||||
|
return Result
|
||||||
|
if Entry:
|
||||||
|
Result = Entry.Copy()
|
||||||
|
if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name):
|
||||||
|
Result.BaseType = t.CStruct(name=TypeName)
|
||||||
|
Result.IsStruct = True
|
||||||
|
return Result
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
if FullName in SymbolTable:
|
||||||
|
Info = SymbolTable[FullName]
|
||||||
|
if Info and Info.IsTypedef:
|
||||||
|
OriginalType = Info.get('OriginalType', '')
|
||||||
|
if OriginalType and 'typedef' in OriginalType:
|
||||||
|
parts = OriginalType.split()
|
||||||
|
if len(parts) >= 2:
|
||||||
|
BaseType_name = parts[1]
|
||||||
|
if not BaseType_name.startswith('C'):
|
||||||
|
BaseType_name = 'C' + BaseType_name
|
||||||
|
CNAME = CTypeHelper.GetCName(BaseType_name)
|
||||||
|
if CNAME:
|
||||||
|
return TypeAnnotationResolver.from_type_name(CNAME)
|
||||||
|
Result = CTypeInfo()
|
||||||
|
Result.BaseType = t._CTypedef(TypeName)
|
||||||
|
Result.IsTypedef = True
|
||||||
|
return Result
|
||||||
|
if Info:
|
||||||
|
Result = Info.Copy()
|
||||||
|
if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name):
|
||||||
|
Result.BaseType = t.CStruct(name=TypeName)
|
||||||
|
Result.IsStruct = True
|
||||||
|
return Result
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
return CTypeInfo()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _handle_array_subscript(Node, SymbolTable):
|
||||||
|
if not isinstance(Node, ast.Subscript):
|
||||||
|
return None
|
||||||
|
dims = []
|
||||||
|
current = Node
|
||||||
|
while isinstance(current, ast.Subscript):
|
||||||
|
if isinstance(current.slice, ast.Constant) and isinstance(current.slice.value, int):
|
||||||
|
dims.insert(0, str(current.slice.value))
|
||||||
|
elif isinstance(current.slice, ast.Name):
|
||||||
|
dims.insert(0, current.slice.id)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
current = current.value
|
||||||
|
base_info = TypeAnnotationResolver.from_node(current, SymbolTable)
|
||||||
|
if base_info and base_info.BaseType:
|
||||||
|
base_info.ArrayDims = dims
|
||||||
|
return base_info
|
||||||
|
return None
|
||||||
Reference in New Issue
Block a user