From 702839936661f586b8b91c39766530d1046883e3 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 11 Sep 2026 21:51:11 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tpv):=20=E6=97=A0=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=E5=88=87=E8=AF=BB=20Spec=EF=BC=88=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE=E7=BA=A7=20TS=5FUINT=20=E4=BC=98=E5=85=88=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 _entry_spec_unsigned:Spec.Kind==TS_UINT 为注解明确无符号的强信号 - _node_type_unsigned 的 Name/Subscript 分支、Attribute 字段分支切读 Spec 优先 - 只切无符号方向(TS_INT 含未表态,不可反推 SIGNED,仍走字符串真源) --- App/lib/core/Gen/Expr/ExprGenOps.vp | 38 ++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 4408edf..4e8102f 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -264,9 +264,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if trans is not None: ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm.id) - if ve is not None and ve.AnnotClassName is not None: - if self._type_name_unsigned(ve.AnnotClassName) != 0: + if ve is not None: + # [S4 切读] Spec 明确无符号(TS_UINT)优先于字符串判定 + if self._entry_spec_unsigned(ve.Spec) != 0: return 1 + if ve.AnnotClassName is not None: + if self._type_name_unsigned(ve.AnnotClassName) != 0: + return 1 return 0 if k == ast.ASTKind.BinOp: bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node) @@ -289,9 +293,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if snm_su.id is not None and trans is not None: ve_su: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry( trans.SymTab, snm_su.id) - if ve_su is not None and ve_su.AnnotClassName is not None: - if self._annot_str_unsigned(ve_su.AnnotClassName) != 0: + if ve_su is not None: + # [S4 切读] Spec 明确无符号优先(数组元素为无符号的联合注解场景 + # 时 Spec 仍是 Ptr/Array ⇒ 返回 0,自动回退字符串路径) + if self._entry_spec_unsigned(ve_su.Spec) != 0: return 1 + if ve_su.AnnotClassName is not None: + if self._annot_str_unsigned(ve_su.AnnotClassName) != 0: + return 1 return 0 if k == ast.ASTKind.Attribute: # 结构体字段(如 viperio.Buf 的 self.capacity/length: sizet): @@ -327,6 +336,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase): self.Gen.StructGen._get_field_entry(st_u, fi_u) if fe_u is not None and fe_u.Name is not None \ and string.strcmp(fe_u.Name, at_u.attr) == 0: + # [S4 切读] 字段 Spec 明确无符号优先 + if self._entry_spec_unsigned(fe_u.Spec) != 0: + return 1 if fe_u.AnnotClassName is not None: if self._annot_str_unsigned(fe_u.AnnotClassName) != 0: return 1 @@ -545,6 +557,24 @@ class ExprGenOps(ExprGenBase.ExprGenBase): def _spec_sign_from_annot(self, annot: str) -> int: """真源入口:注解 → TS_SIGN_*(UNKNOWN 表示不表态)""" return self.Gen.TypeGenCType.spec_sign_of_annot(annot, 0) + # ============================================================ + # _entry_spec_unsigned - 变量/字段条目的 Spec 是否**明确无符号整数** + # + # S4 切读:条目的 Spec 由 SpecFromLLVMType 反推(恒 TS_INT)+ SpecWithSign + # 按注解切 TS_UINT。因此 `Kind == TS_UINT` 是**注解明确表态无符号**的强信号, + # 可优先于 AnnotClassName 字符串判定直接采用。 + # + # ⚠️ 反向不成立:`Kind == TS_INT` 既可能是"注解有符号"也可能是"未表态" + # (SpecFromLLVMType 默认),**不可**据此断言 SIGNED —— 故只切无符号方向, + # 有符号仍走 AnnotClassName 字符串真源(避免把未表态误判成 signed)。 + # ============================================================ + def _entry_spec_unsigned(self, sp: TSpec.TypeSpec | t.CPtr) -> int: + """Spec 是否明确无符号整数(TS_UINT);其它一律 0(未表态/不适用)""" + if sp is None: + return 0 + if sp.Kind == TSpec.TS_UINT: + return 1 + return 0 def _type_name_unsigned(self, type_name: str) -> int: """[S3 切读] 类型名无符号判定:新真源优先,未表态时回退旧路径