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

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

@@ -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 调用)