阶段 2 完成
This commit is contained in:
@@ -7,7 +7,8 @@ from lib.includes import t
|
||||
|
||||
import ast
|
||||
from typing import List, Dict
|
||||
from enum import IntFlag, auto
|
||||
from enum import IntFlag, auto
|
||||
from lib.core.TypeSpec import TypeSpec, SymbolMeta, FIELD_ROUTES
|
||||
|
||||
|
||||
EXCEPTION_CODE_MAP = {
|
||||
@@ -66,57 +67,72 @@ class CTypeInfo:
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._BaseType: t.CType = None
|
||||
self.PtrCount: int = 0
|
||||
self.VarConst: bool = False
|
||||
self.VarVolatile: bool = False
|
||||
self.DataConst: bool = False
|
||||
self.DataVolatile: bool = False
|
||||
self.ArrayDims: List[str] = []
|
||||
self.Storage: t.CType = None
|
||||
self.IsFuncPtr: bool = False
|
||||
self.FuncPtrParams: List[Tuple[str, 'CTypeInfo']] = [] # 函数指针参数列表:(参数名, 参数类型)
|
||||
self.FuncParamNames: List[str] = [] # 函数参数名列表
|
||||
self.FuncPtrReturn: "CTypeInfo" = None
|
||||
self.IsBitField: bool = False
|
||||
self.BitWidth: int = 0
|
||||
self.ByteOrder: str = "" # "big", "little", or ""
|
||||
self.IsTypedef: bool = False
|
||||
self.IsStruct: bool = False
|
||||
self.IsEnum: bool = False
|
||||
self.IsUnion: bool = False
|
||||
self.IsRenum: bool = False
|
||||
self.RenumVariants: list = []
|
||||
self.Name: str = ""
|
||||
self.Members: Dict[str, 'CTypeInfo'] = {}
|
||||
self.OriginalType: "CTypeInfo" = None
|
||||
self.DeclaredType: str = ""
|
||||
self.CreturnTypes: list = []
|
||||
self.Lineno: int = 0
|
||||
self.file: str = ""
|
||||
self.IsAnonymous: bool = False
|
||||
self.IsCpythonObject: bool = False
|
||||
self.IsEnumMember: bool = False
|
||||
self.IsVariadic: bool = False
|
||||
self.IsVariable: bool = False
|
||||
self.IsFunction: bool = False
|
||||
self.MetaList: FuncMeta = FuncMeta.NONE
|
||||
self.IsArrayPtr: bool = False
|
||||
self.ArrayPtr: 'CTypeInfo' = None
|
||||
self.IsState: bool = False
|
||||
self.IsDefine: bool = False
|
||||
self.DefineValue = None
|
||||
self.IsInline: bool = False
|
||||
self.InlineBody: list = None
|
||||
self.InlineParams: list = None
|
||||
self.ModuleName: str = ""
|
||||
self._extra: dict = {}
|
||||
object.__setattr__(self, '_ts', TypeSpec())
|
||||
sm = SymbolMeta()
|
||||
sm.meta_list = FuncMeta.NONE
|
||||
object.__setattr__(self, '_sm', sm)
|
||||
|
||||
# --- 新公共 API:供新代码直接访问 TypeSpec / SymbolMeta / SymbolKind ---
|
||||
@property
|
||||
def ts(self) -> TypeSpec:
|
||||
"""TypeSpec — 纯类型描述(只读)"""
|
||||
return self._ts
|
||||
|
||||
@property
|
||||
def sm(self) -> SymbolMeta:
|
||||
"""SymbolMeta — 符号表元数据(只读)"""
|
||||
return self._sm
|
||||
|
||||
@property
|
||||
def kind(self) -> 'SymbolKind':
|
||||
"""SymbolKind — 符号类型种类枚举"""
|
||||
return self._sm.kind
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
"""属性设置路由 — 将旧字段名委托到 _ts/_sm/_kind_flags"""
|
||||
if name == 'BaseType':
|
||||
# BaseType 有复杂的 property setter(自动设置 IsStruct/IsEnum/IsUnion)
|
||||
CTypeInfo.BaseType.fset(self, value)
|
||||
return
|
||||
if name in ('_ts', '_sm', 'ts', 'sm', 'kind'):
|
||||
# _ts/_sm 内部字段直接设置;ts/sm/kind 是只读 property,禁止设置
|
||||
if name in ('ts', 'sm', 'kind'):
|
||||
raise AttributeError(f"'CTypeInfo' attribute '{name}' is read-only")
|
||||
object.__setattr__(self, name, value)
|
||||
return
|
||||
if name in FIELD_ROUTES:
|
||||
target, field = FIELD_ROUTES[name]
|
||||
if target == 'ts':
|
||||
setattr(self._ts, field, value)
|
||||
elif target == 'sm':
|
||||
setattr(self._sm, field, value)
|
||||
elif target == 'kf':
|
||||
self._sm._kind_flags[field] = value
|
||||
return
|
||||
object.__setattr__(self, name, value)
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""属性读取路由 — 将旧字段名委托到 _ts/_sm/_kind_flags"""
|
||||
try:
|
||||
ts = object.__getattribute__(self, '_ts')
|
||||
sm = object.__getattribute__(self, '_sm')
|
||||
except AttributeError:
|
||||
raise AttributeError(f"'CTypeInfo' object has no attribute '{name}'")
|
||||
if name in FIELD_ROUTES:
|
||||
target, field = FIELD_ROUTES[name]
|
||||
if target == 'ts':
|
||||
return getattr(ts, field)
|
||||
elif target == 'sm':
|
||||
return getattr(sm, field)
|
||||
elif target == 'kf':
|
||||
return sm._kind_flags.get(field, False)
|
||||
raise AttributeError(f"'CTypeInfo' object has no attribute '{name}'")
|
||||
|
||||
|
||||
|
||||
@property
|
||||
def BaseType(self) -> t.CType | tuple:
|
||||
return self._BaseType
|
||||
return self._ts._base_type
|
||||
|
||||
@BaseType.setter
|
||||
def BaseType(self, value: t.CType | type | tuple | List):
|
||||
@@ -127,54 +143,57 @@ class CTypeInfo:
|
||||
- type (CType 子类): 如 t.CStruct,自动实例化
|
||||
- tuple/list of t.CType: 多个组合类型
|
||||
"""
|
||||
ts = self._ts
|
||||
kf = self._sm._kind_flags
|
||||
|
||||
if value is None:
|
||||
self._BaseType = None
|
||||
self.IsStruct = False
|
||||
self.IsEnum = False
|
||||
self.IsUnion = False
|
||||
self.IsRenum = False
|
||||
ts._base_type = None
|
||||
kf['IsStruct'] = False
|
||||
kf['IsEnum'] = False
|
||||
kf['IsUnion'] = False
|
||||
kf['IsRenum'] = False
|
||||
return
|
||||
|
||||
if isinstance(value, (tuple, list)):
|
||||
self._BaseType = tuple(value)
|
||||
ts._base_type = tuple(value)
|
||||
for v in value:
|
||||
if isinstance(v, t.CStruct):
|
||||
self.IsStruct = True
|
||||
kf['IsStruct'] = True
|
||||
elif isinstance(v, t.CEnum):
|
||||
self.IsEnum = True
|
||||
kf['IsEnum'] = True
|
||||
elif isinstance(v, t.CUnion):
|
||||
self.IsUnion = True
|
||||
kf['IsUnion'] = True
|
||||
elif isinstance(v, t.REnum):
|
||||
self.IsRenum = True
|
||||
self.IsEnum = True
|
||||
kf['IsRenum'] = True
|
||||
kf['IsEnum'] = True
|
||||
return
|
||||
|
||||
if isinstance(value, type) and issubclass(value, t.CType):
|
||||
self._BaseType = value()
|
||||
ts._base_type = value()
|
||||
return
|
||||
|
||||
if isinstance(value, t.CType):
|
||||
self._BaseType = value
|
||||
ts._base_type = value
|
||||
if isinstance(value, t.CStruct):
|
||||
self.IsStruct = True
|
||||
self.IsEnum = False
|
||||
self.IsUnion = False
|
||||
self.IsRenum = False
|
||||
kf['IsStruct'] = True
|
||||
kf['IsEnum'] = False
|
||||
kf['IsUnion'] = False
|
||||
kf['IsRenum'] = False
|
||||
elif isinstance(value, t.REnum):
|
||||
self.IsRenum = True
|
||||
self.IsEnum = True
|
||||
self.IsStruct = False
|
||||
self.IsUnion = False
|
||||
kf['IsRenum'] = True
|
||||
kf['IsEnum'] = True
|
||||
kf['IsStruct'] = False
|
||||
kf['IsUnion'] = False
|
||||
elif isinstance(value, t.CEnum):
|
||||
self.IsEnum = True
|
||||
self.IsStruct = False
|
||||
self.IsUnion = False
|
||||
self.IsRenum = False
|
||||
kf['IsEnum'] = True
|
||||
kf['IsStruct'] = False
|
||||
kf['IsUnion'] = False
|
||||
kf['IsRenum'] = False
|
||||
elif isinstance(value, t.CUnion):
|
||||
self.IsUnion = True
|
||||
self.IsStruct = False
|
||||
self.IsEnum = False
|
||||
self.IsRenum = False
|
||||
kf['IsUnion'] = True
|
||||
kf['IsStruct'] = False
|
||||
kf['IsEnum'] = False
|
||||
kf['IsRenum'] = False
|
||||
return
|
||||
|
||||
raise TypeError(f"BaseType must be t.CType instance, type subclass, or tuple of t.CType, got {type(value)}")
|
||||
@@ -182,82 +201,92 @@ class CTypeInfo:
|
||||
@property
|
||||
def TypeCls(self):
|
||||
"""获取 CType 类(从 BaseType 推断)"""
|
||||
if self.BaseType:
|
||||
return type(self.BaseType)
|
||||
if self.IsStruct:
|
||||
bt = self._ts._base_type
|
||||
if bt:
|
||||
return type(bt)
|
||||
kf = self._sm._kind_flags
|
||||
if kf.get('IsStruct'):
|
||||
return t.CStruct
|
||||
if self.IsEnum:
|
||||
if kf.get('IsEnum'):
|
||||
return t.CEnum
|
||||
if self.IsUnion:
|
||||
if kf.get('IsUnion'):
|
||||
return t.CUnion
|
||||
if self.IsTypedef:
|
||||
if kf.get('IsTypedef'):
|
||||
return t._CTypedef
|
||||
return None
|
||||
|
||||
@property
|
||||
def IsPtr(self) -> bool:
|
||||
return self.PtrCount > 0
|
||||
return self._ts.ptr_count > 0
|
||||
|
||||
@property
|
||||
def IsVoid(self) -> bool:
|
||||
return isinstance(self.BaseType, t.CVoid)
|
||||
return isinstance(self._ts._base_type, t.CVoid)
|
||||
|
||||
@property
|
||||
def IsStr(self) -> bool:
|
||||
return isinstance(self.BaseType, t.CChar) and self.PtrCount > 0
|
||||
return isinstance(self._ts._base_type, t.CChar) and self._ts.ptr_count > 0
|
||||
|
||||
@property
|
||||
def IsInt(self) -> bool:
|
||||
return isinstance(self.BaseType, t.CType) and getattr(self.BaseType, 'IsSigned', None) is not None and self.BaseType.IsSigned is True and not self.IsVoid
|
||||
bt = self._ts._base_type
|
||||
return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is not None and bt.IsSigned is True and not isinstance(bt, t.CVoid)
|
||||
|
||||
@property
|
||||
def IsUInt(self) -> bool:
|
||||
return isinstance(self.BaseType, t.CType) and getattr(self.BaseType, 'IsSigned', None) is False
|
||||
bt = self._ts._base_type
|
||||
return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is False
|
||||
|
||||
@property
|
||||
def IsFloat(self) -> bool:
|
||||
bt = self.BaseType
|
||||
bt = self._ts._base_type
|
||||
return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is None and getattr(bt, 'Size', 0) in (32, 64, 128) and not isinstance(bt, t.CVoid)
|
||||
|
||||
@property
|
||||
def IsDouble(self) -> bool:
|
||||
return isinstance(self.BaseType, t.CDouble) or (isinstance(self.BaseType, t.CFloat64T))
|
||||
bt = self._ts._base_type
|
||||
return isinstance(bt, t.CDouble) or isinstance(bt, t.CFloat64T)
|
||||
|
||||
@property
|
||||
def IsPointerToChar(self) -> bool:
|
||||
return isinstance(self.BaseType, t.CChar) and self.PtrCount > 0
|
||||
return isinstance(self._ts._base_type, t.CChar) and self._ts.ptr_count > 0
|
||||
|
||||
def ToString(self) -> str:
|
||||
if self.IsFuncPtr:
|
||||
ts = self._ts
|
||||
sm = self._sm
|
||||
kf = sm._kind_flags
|
||||
bt = ts._base_type
|
||||
|
||||
if ts.is_func_ptr:
|
||||
return 'Callable'
|
||||
parts = []
|
||||
|
||||
if self.Storage and not isinstance(self.Storage, t.CExport):
|
||||
parts.append(self.Storage.CName)
|
||||
if ts.storage and not isinstance(ts.storage, t.CExport):
|
||||
parts.append(ts.storage.CName)
|
||||
|
||||
if self.DataConst or self.DataVolatile:
|
||||
if ts.data_const or ts.data_volatile:
|
||||
qualifiers = []
|
||||
if self.DataConst:
|
||||
if ts.data_const:
|
||||
qualifiers.append("const")
|
||||
if self.DataVolatile:
|
||||
if ts.data_volatile:
|
||||
qualifiers.append("volatile")
|
||||
parts.append("_".join(qualifiers))
|
||||
|
||||
if self.IsTypedef and self.Name:
|
||||
return self.Name
|
||||
elif self.IsRenum and self.Name:
|
||||
base_name = self.Name
|
||||
elif self.BaseType:
|
||||
base_name = getattr(self.BaseType, 'CName', None) or (self.BaseType if isinstance(self.BaseType, str) else str(self.BaseType))
|
||||
if kf.get('IsTypedef') and sm.name:
|
||||
return sm.name
|
||||
elif kf.get('IsRenum') and sm.name:
|
||||
base_name = sm.name
|
||||
elif bt:
|
||||
base_name = getattr(bt, 'CName', None) or (bt if isinstance(bt, str) else str(bt))
|
||||
else:
|
||||
base_name = "void"
|
||||
|
||||
if self.IsArrayPtr:
|
||||
if ts.is_array_ptr:
|
||||
ptr_str = ""
|
||||
if self.PtrCount > 0:
|
||||
ptr_str = "*" * self.PtrCount
|
||||
if self.ArrayPtr:
|
||||
inner = self.ArrayPtr.ToString()
|
||||
if ts.ptr_count > 0:
|
||||
ptr_str = "*" * ts.ptr_count
|
||||
if ts.array_ptr:
|
||||
inner = ts.array_ptr.ToString()
|
||||
if ptr_str:
|
||||
parts.append(f"{base_name} {ptr_str}({inner})")
|
||||
else:
|
||||
@@ -267,22 +296,22 @@ class CTypeInfo:
|
||||
parts.append(f"{base_name} {ptr_str}()")
|
||||
else:
|
||||
parts.append(f"{base_name} ()")
|
||||
elif self.ArrayPtr:
|
||||
inner = self.ArrayPtr.ToString()
|
||||
if self.PtrCount > 0:
|
||||
parts.append(f"{base_name} {'*' * self.PtrCount}({inner})")
|
||||
elif ts.array_ptr:
|
||||
inner = ts.array_ptr.ToString()
|
||||
if ts.ptr_count > 0:
|
||||
parts.append(f"{base_name} {'*' * ts.ptr_count}({inner})")
|
||||
else:
|
||||
parts.append(f"{base_name} ({inner})")
|
||||
else:
|
||||
parts.append(base_name)
|
||||
if self.PtrCount > 0:
|
||||
parts.append("*" * self.PtrCount)
|
||||
if self.VarConst:
|
||||
if ts.ptr_count > 0:
|
||||
parts.append("*" * ts.ptr_count)
|
||||
if ts.var_const:
|
||||
parts.append("const")
|
||||
if self.VarVolatile:
|
||||
if ts.var_volatile:
|
||||
parts.append("volatile")
|
||||
|
||||
for dim in self.ArrayDims:
|
||||
for dim in ts.array_dims:
|
||||
if dim:
|
||||
parts.append(f"[{dim}]")
|
||||
else:
|
||||
@@ -1098,58 +1127,28 @@ class CTypeInfo:
|
||||
|
||||
def Copy(self) -> "CTypeInfo":
|
||||
NewInfo = CTypeInfo()
|
||||
NewInfo.BaseType = self.BaseType
|
||||
NewInfo.PtrCount = self.PtrCount
|
||||
NewInfo.VarConst = self.VarConst
|
||||
NewInfo.VarVolatile = self.VarVolatile
|
||||
NewInfo.DataConst = self.DataConst
|
||||
NewInfo.DataVolatile = self.DataVolatile
|
||||
NewInfo.ArrayDims = list(self.ArrayDims)
|
||||
NewInfo.Storage = self.Storage
|
||||
NewInfo.IsFuncPtr = self.IsFuncPtr
|
||||
NewInfo.FuncPtrParams = list(self.FuncPtrParams)
|
||||
NewInfo.FuncParamNames = list(self.FuncParamNames)
|
||||
NewInfo.FuncPtrReturn = self.FuncPtrReturn.Copy() if isinstance(self.FuncPtrReturn, CTypeInfo) else self.FuncPtrReturn
|
||||
NewInfo.IsBitField = self.IsBitField
|
||||
NewInfo.BitWidth = self.BitWidth
|
||||
NewInfo.IsTypedef = self.IsTypedef
|
||||
NewInfo.IsStruct = self.IsStruct
|
||||
NewInfo.IsEnum = self.IsEnum
|
||||
NewInfo.IsUnion = self.IsUnion
|
||||
NewInfo.IsRenum = self.IsRenum
|
||||
NewInfo.RenumVariants = list(self.RenumVariants)
|
||||
NewInfo.Name = self.Name
|
||||
NewInfo.Members = dict(self.Members)
|
||||
NewInfo.OriginalType = self.OriginalType.Copy() if isinstance(self.OriginalType, CTypeInfo) else self.OriginalType
|
||||
NewInfo.DeclaredType = self.DeclaredType
|
||||
NewInfo.CreturnTypes = list(self.CreturnTypes)
|
||||
NewInfo.Lineno = self.Lineno
|
||||
NewInfo.file = self.file
|
||||
NewInfo.IsAnonymous = self.IsAnonymous
|
||||
NewInfo.IsCpythonObject = self.IsCpythonObject
|
||||
NewInfo.IsEnumMember = self.IsEnumMember
|
||||
NewInfo.IsVariadic = self.IsVariadic
|
||||
NewInfo.IsVariable = self.IsVariable
|
||||
NewInfo.IsFunction = self.IsFunction
|
||||
NewInfo.MetaList = self.MetaList
|
||||
NewInfo.IsArrayPtr = self.IsArrayPtr
|
||||
NewInfo.ArrayPtr = self.ArrayPtr.Copy() if self.ArrayPtr else None
|
||||
NewInfo.IsState = self.IsState
|
||||
NewInfo.IsDefine = self.IsDefine
|
||||
NewInfo.DefineValue = self.DefineValue
|
||||
NewInfo.IsInline = self.IsInline
|
||||
NewInfo.InlineBody = self.InlineBody
|
||||
NewInfo.InlineParams = list(self.InlineParams) if self.InlineParams else None
|
||||
NewInfo._extra = dict(self._extra)
|
||||
NewInfo._ts = self._ts.copy()
|
||||
NewInfo._sm = self._sm.copy()
|
||||
# CTypeInfo 引用字段需要深拷贝
|
||||
if isinstance(NewInfo._ts.func_ptr_return, CTypeInfo):
|
||||
NewInfo._ts.func_ptr_return = NewInfo._ts.func_ptr_return.Copy()
|
||||
if isinstance(NewInfo._ts.original_type, CTypeInfo):
|
||||
NewInfo._ts.original_type = NewInfo._ts.original_type.Copy()
|
||||
if NewInfo._ts.array_ptr:
|
||||
NewInfo._ts.array_ptr = NewInfo._ts.array_ptr.Copy()
|
||||
# 实例上的动态属性也需要拷贝(如 IsSigned 等)
|
||||
for key, val in self.__dict__.items():
|
||||
if key not in ('_ts', '_sm'):
|
||||
object.__setattr__(NewInfo, key, val)
|
||||
return NewInfo
|
||||
|
||||
def get(self, key, default=None):
|
||||
"""获取额外属性"""
|
||||
return self._extra.get(key, default)
|
||||
return self._sm._extra.get(key, default)
|
||||
|
||||
def set(self, key, value):
|
||||
"""设置额外属性"""
|
||||
self._extra[key] = value
|
||||
self._sm._extra[key] = value
|
||||
|
||||
@staticmethod
|
||||
def VoidTypeInfo() -> "CTypeInfo":
|
||||
@@ -1173,7 +1172,9 @@ class CTypeInfo:
|
||||
return self.ToString()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CTypeInfo(BaseType={self.BaseType}, PtrCount={self.PtrCount}, IsTypedef={self.IsTypedef}, OriginalType={self.OriginalType!r}, VarConst={self.VarConst}, DataConst={self.DataConst})"
|
||||
ts = self._ts
|
||||
kf = self._sm._kind_flags
|
||||
return f"CTypeInfo(BaseType={ts._base_type}, PtrCount={ts.ptr_count}, IsTypedef={kf.get('IsTypedef', False)}, OriginalType={ts.original_type!r}, VarConst={ts.var_const}, DataConst={ts.data_const})"
|
||||
|
||||
|
||||
class CTypeHelper:
|
||||
|
||||
@@ -3,7 +3,6 @@ from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from lib.core.translator import Translator
|
||||
from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta
|
||||
from lib.core.SymbolNode import SymbolNode
|
||||
from lib.includes import t
|
||||
import ast
|
||||
import llvmlite.ir as ir
|
||||
@@ -658,13 +657,10 @@ class ClassHandle(BaseHandle):
|
||||
union_type = ir.IdentifiedStructType(Gen.module, ClassName)
|
||||
union_type.set_body(ir.ArrayType(ir.IntType(8), max_size))
|
||||
Gen.structs[ClassName] = union_type
|
||||
UnionNode = SymbolNode.CreateClass(
|
||||
name=ClassName,
|
||||
TypeKind='union',
|
||||
lineno=Node.lineno,
|
||||
file='<stdin>'
|
||||
)
|
||||
self.Trans.SymbolTable[ClassName] = UnionNode.attributes
|
||||
UnionNode = CTypeInfo()
|
||||
UnionNode.Name = ClassName
|
||||
UnionNode.IsUnion = True
|
||||
self.Trans.SymbolTable[ClassName] = UnionNode
|
||||
|
||||
def _EmitREnumLlvm(self, Node, Gen):
|
||||
ClassName = Node.name
|
||||
|
||||
@@ -567,10 +567,18 @@ class ExprCallHandle(BaseHandle):
|
||||
LastPart in ModuleSha1Map)
|
||||
# 最后尝试: 用 FuncAttr 直接查找 Gen.functions(_find_function 会遍历 SHA1 前缀)
|
||||
if FuncAttr and ModulePath and ModulePath not in {'t', 'c'}:
|
||||
# 先检查 FuncAttr 是否是函数/变量,如果是则跳过 struct 声明
|
||||
_attr_sym = self.Trans.SymbolTable.get(FuncAttr)
|
||||
_is_func_or_var = _attr_sym and (getattr(_attr_sym, 'IsFunction', False) or getattr(_attr_sym, 'IsVariable', False))
|
||||
if not _is_func_or_var and ModulePath:
|
||||
_full_key = f"{ModulePath}.{FuncAttr}"
|
||||
_full_sym = self.Trans.SymbolTable.get(_full_key)
|
||||
if _full_sym and (getattr(_full_sym, 'IsFunction', False) or getattr(_full_sym, 'IsVariable', False)):
|
||||
_is_func_or_var = True
|
||||
# 优先检查 FuncAttr 是否为 struct/类构造器
|
||||
if FuncAttr not in Gen.structs:
|
||||
if not _is_func_or_var and FuncAttr not in Gen.structs:
|
||||
self._ensure_struct_declared(FuncAttr)
|
||||
if FuncAttr in Gen.structs:
|
||||
if not _is_func_or_var and FuncAttr in Gen.structs:
|
||||
result = self._HandleClassNewLlvm(Node, FuncAttr)
|
||||
if result is not None:
|
||||
return result
|
||||
@@ -639,6 +647,10 @@ class ExprCallHandle(BaseHandle):
|
||||
|
||||
def _ensure_struct_declared(self, class_name):
|
||||
Gen = self.Trans.LlvmGen
|
||||
# 如果名称是函数或变量,不应创建 struct
|
||||
SymInfo = self.Trans.SymbolTable.get(class_name)
|
||||
if SymInfo and (getattr(SymInfo, 'IsFunction', False) or getattr(SymInfo, 'IsVariable', False)):
|
||||
return
|
||||
if class_name in Gen.structs:
|
||||
existing = Gen.structs[class_name]
|
||||
if isinstance(existing, ir.IdentifiedStructType) and (existing.elements is None or len(existing.elements) == 0):
|
||||
|
||||
Reference in New Issue
Block a user