进行了优化,减少了上帝结构体的符号表占用
This commit is contained in:
@@ -359,44 +359,16 @@ class CTypeInfo:
|
||||
@staticmethod
|
||||
def FromTypeName(TypeName: str) -> "CTypeInfo":
|
||||
"""从简单类型名构造 CTypeInfo(不经过 FromStr 字符串解析)"""
|
||||
from lib.core.Handles.HandlesBase import BuiltinTypeMap
|
||||
|
||||
# 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
|
||||
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver
|
||||
return TypeAnnotationResolver.from_type_name(TypeName)
|
||||
|
||||
# FromStr 已移除 - 类型解析不再经过中间字符串格式
|
||||
# typedef 展开直接走 CTypeInfo 对象,不经过字符串解析
|
||||
|
||||
@staticmethod
|
||||
def TryEvalConstExpr(node, SymbolTable):
|
||||
from lib.core.ConstEvaluator import ConstEvaluator
|
||||
return ConstEvaluator.eval_with_symtab(node, SymbolTable)
|
||||
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver
|
||||
return TypeAnnotationResolver.try_eval_const_expr(node, SymbolTable)
|
||||
|
||||
@classmethod
|
||||
def FromNode(cls, Node: ast.AST, SymbolTable: dict) -> "CTypeInfo":
|
||||
@@ -406,658 +378,9 @@ class CTypeInfo:
|
||||
Node: AST 节点(如 ast.Name, ast.Attribute 等)
|
||||
SymbolTable: 符号表字典
|
||||
"""
|
||||
if isinstance(Node, (ast.Constant, ast.Str)):
|
||||
return cls._FromNode_Constant(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()
|
||||
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver
|
||||
return TypeAnnotationResolver.from_node(Node, SymbolTable)
|
||||
|
||||
@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":
|
||||
NewInfo = CTypeInfo()
|
||||
|
||||
Reference in New Issue
Block a user