进行了优化,减少了上帝结构体的符号表占用
This commit is contained in:
@@ -19,6 +19,9 @@ class SymbolTable:
|
||||
self._symbols: Dict[str, CTypeInfo] = {}
|
||||
from lib.core.DiagnosticCollector import DiagnosticCollector
|
||||
self.diagnostics = DiagnosticCollector()
|
||||
from lib.core.LLVMTypeMapper import LLVMTypeMapper
|
||||
self._type_mapper = LLVMTypeMapper(self)
|
||||
self.import_aliases: Dict[str, str] = {}
|
||||
|
||||
def clear(self):
|
||||
self._symbols.clear()
|
||||
@@ -69,6 +72,99 @@ class SymbolTable:
|
||||
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
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]:
|
||||
"""序列化为字典格式"""
|
||||
@@ -217,183 +313,24 @@ class SymbolTable:
|
||||
return []
|
||||
|
||||
# ==================================================================
|
||||
# 类型解析辅助方法(供 TypeResolver 通过 SymbolTable 引用调用)
|
||||
# 类型解析辅助方法(委托到 LLVMTypeMapper)
|
||||
# ==================================================================
|
||||
|
||||
|
||||
def _GetLLVMTypeStr(self, node):
|
||||
if node is None:
|
||||
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'
|
||||
return self._type_mapper.get_llvm_type_str(node)
|
||||
|
||||
def _GetFuncRetTypeStr(self, returns_node):
|
||||
if returns_node is None:
|
||||
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'
|
||||
return self._type_mapper.get_func_ret_type_str(returns_node)
|
||||
|
||||
@staticmethod
|
||||
def _CheckAnnotationHasCInline(annotation_node) -> bool:
|
||||
return _CheckAnnotationHasCInline(annotation_node)
|
||||
|
||||
def _GetFuncParamTypeStr(self, annotation_node):
|
||||
if annotation_node is None:
|
||||
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*'
|
||||
return self._type_mapper.get_func_param_type_str(annotation_node)
|
||||
|
||||
def _ResolveTypedefValueType(self, node):
|
||||
if node is None:
|
||||
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 ''
|
||||
return self._type_mapper.resolve_typedef_value_type(node)
|
||||
|
||||
# ==================================================================
|
||||
# 符号插入方法(供 SymbolInserter / PackageReexporter 调用)
|
||||
|
||||
Reference in New Issue
Block a user