进行了优化,减少了上帝结构体的符号表占用

This commit is contained in:
2026-06-18 22:12:14 +08:00
parent d7b98cc9c5
commit 19f2787db0
32 changed files with 1245 additions and 1083 deletions

View File

@@ -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()