feat(tpv): Spec 注解侧填符号性(SpecWithSign + 变量/字段接入)
- TypeSpec 新增 SpecWithSign:整数 TS_INT↔TS_UINT 切换 + 驻留(SpecToText 键区分符号) - set_var_annot_class_name 接入:注解类名提取符号性,补 Spec 无符号性 - add_field 接入:字段注解类名提取符号性,补 Spec 无符号性
This commit is contained in:
1 parent
0a108e6289
commit
7fedf8daad
3 files changed
+65
No files matched your search
@@ -407,6 +407,12 @@ class StructGenMixin:
|
||||
arena_f: TSpec.TypeSpecArena | t.CPtr = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
if arena_f is not None:
|
||||
fe.Spec = TSpec.SpecFromLLVMType(arena_f, field_ty)
|
||||
# [S4 注解侧填 Spec] 补字段 Spec 整数符号性(annot_class_name 携带
|
||||
# 真实无符号性;LLVM 反推恒 TS_INT)
|
||||
if fe.Spec is not None and annot_class_name is not None:
|
||||
sign_f: int = self.Gen.TypeGenCType.spec_sign_of_annot(annot_class_name)
|
||||
if sign_f != TSpec.TS_SIGN_UNKNOWN:
|
||||
fe.Spec = TSpec.SpecWithSign(arena_f, fe.Spec, sign_f)
|
||||
|
||||
struct_entry.FieldCount = idx + 1
|
||||
return idx
|
||||
|
||||
@@ -817,6 +817,56 @@ def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr:
|
||||
return sp.Elem
|
||||
|
||||
|
||||
# ============================================================
|
||||
# SpecWithSign - 复制 Spec 并按注解覆盖整数符号性(TS_INT ↔ TS_UINT)
|
||||
#
|
||||
# 背景(S4 注解侧填 Spec):SpecFromLLVMType 从 LLVM 类型反推时,整数恒
|
||||
# TS_INT(LLVM iN 不分符号)。但 SpecToText 对 TS_INT 编 "i%d"、TS_UINT 编
|
||||
# "u%d",符号性由 **Kind** 区分 —— 若只改 IsSigned 不改 Kind,两个符号性不同
|
||||
# 的整数会得到相同驻留键 "i%d" 而撞键(同键不同义,返回错误实例)。
|
||||
# 注解侧知道真实符号性(uint32 等无符号名),须把 TS_INT 切为 TS_UINT。
|
||||
#
|
||||
# 浅拷贝结构(Elem/Ret/Params 指针共享已驻留子实例);仅当符号性实际变化才
|
||||
# 复制并驻留,否则返回原实例。驻留去重 ⇒ 同「结构+符号」共享一份。
|
||||
# ============================================================
|
||||
def SpecWithSign(arena: TypeSpecArena | t.CPtr,
|
||||
sp: TypeSpec | t.CPtr,
|
||||
is_signed: int) -> TypeSpec | t.CPtr:
|
||||
"""复制 sp 并覆盖整数符号性,驻留后返回;无变化返回原实例,失败返回 None"""
|
||||
if sp is None:
|
||||
return None
|
||||
new_kind: int = sp.Kind
|
||||
new_signed: int = sp.IsSigned
|
||||
if is_signed == TS_SIGN_UNSIGNED and sp.Kind == TS_INT:
|
||||
new_kind = TS_UINT
|
||||
new_signed = TS_SIGN_UNSIGNED
|
||||
elif is_signed == TS_SIGN_SIGNED and sp.Kind == TS_UINT:
|
||||
new_kind = TS_INT
|
||||
new_signed = TS_SIGN_SIGNED
|
||||
if new_kind == sp.Kind:
|
||||
return sp
|
||||
cp: TypeSpec | t.CPtr = _spec_alloc()
|
||||
if cp is None:
|
||||
return None
|
||||
cp.Kind = new_kind
|
||||
cp.Bits = sp.Bits
|
||||
cp.IsSigned = new_signed
|
||||
cp.PtrLevel = sp.PtrLevel
|
||||
cp.Elem = sp.Elem
|
||||
cp.ArrayCount = sp.ArrayCount
|
||||
cp.BaseName = sp.BaseName
|
||||
cp.Ret = sp.Ret
|
||||
cp.Params = sp.Params
|
||||
cp.ParamCount = sp.ParamCount
|
||||
cp.IsVarArg = sp.IsVarArg
|
||||
cp.Storage = sp.Storage
|
||||
cp.ElemBits = sp.ElemBits
|
||||
cp.IsElemPtr = sp.IsElemPtr
|
||||
cp.DerefBase = sp.DerefBase
|
||||
cp.Ty = sp.Ty
|
||||
return InternSpec(arena, cp)
|
||||
|
||||
|
||||
def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int:
|
||||
"""是否无符号整数(单一真源;未知返回 0)"""
|
||||
if sp is None:
|
||||
|
||||
@@ -129,6 +129,15 @@ class VarGenMixin:
|
||||
if entry is None:
|
||||
return 1
|
||||
entry.AnnotClassName = class_name
|
||||
# [S4 注解侧填 Spec] 补 Spec 整数符号性:SpecFromLLVMType 反推恒 TS_INT
|
||||
# (LLVM iN 不分符号),注解类名携带真实无符号性(uint32/CUInt32T 等)。
|
||||
# 切 TS_INT→TS_UINT 供后续消费者切读(逐步替代 AnnotClassName 的符号性判断)。
|
||||
if entry.Spec is not None and class_name is not None:
|
||||
sign: int = self.Gen.TypeGenCType.spec_sign_of_annot(class_name)
|
||||
if sign != TSpec.TS_SIGN_UNKNOWN:
|
||||
arena_sn: TSpec.TypeSpecArena | t.CPtr = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
if arena_sn is not None:
|
||||
entry.Spec = TSpec.SpecWithSign(arena_sn, entry.Spec, sign)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
|
||||
Reference in new issue
Block a user