diff --git a/lib/Projectrans/DeclarationGenerator.py b/lib/Projectrans/DeclarationGenerator.py index 44ee0f2..39b4f88 100644 --- a/lib/Projectrans/DeclarationGenerator.py +++ b/lib/Projectrans/DeclarationGenerator.py @@ -1121,10 +1121,29 @@ class DeclarationGenerator: 下标(rawptr[...] / t.CPtr[...])不是裸类引用——它们已自带指针层数, 须逐层外包(rawptr[Node] | t.CPtr → Node**、ast.AST | t.CPtr | t.CPtr → AST**,与定义端整体拉平后只吸收一次 CPtr 一致)。 + + **例外:纯装饰器标记联合**。`t.CExtern | X` / `t.CExport | X` / `t.State | X` + (vpi 记录的模块级全局就是这种写法,见 lib.Phase.Phase1.__init__.vpi 的 + `_mbuddy: t.CExtern | memhub.MemBuddy | t.CPtr`)里标记侧展开为**空串** + (CTypeRegistry.NameToLLVM('CExtern') == ''),该联合语义上仍是 X 这一个 + 裸类引用,故 `t.CExtern | X | t.CPtr` 必须与 `X | t.CPtr` 同判(吸收)—— + 对齐 TPV TypeGenResolve 的第 3 条语义「ActualType | DecoratorMarker → + ActualType」。漏此判据时联合被当成"已自带指针层数的左值"而多外包一层: + 声明端 `%"sha1.X"**` 与定义端 `%"sha1.X"*` 差一层,消费模块里 + `self.__mbuddy__ = _mbuddy` 之类的赋值即报"层数不同"fail-fast。 """ if not inner_type: return False if isinstance(inner, ast.BinOp): + if not isinstance(inner.op, ast.BitOr): + return False + LeftType: str = self._get_type_str(inner.left) + RightType: str = self._get_type_str(inner.right) + # 恰一侧是纯装饰器标记(展开为空/void)⇒ 类型全部来自另一侧,按另一侧判 + if LeftType in ('', 'void') and RightType not in ('', 'void'): + return self._is_bare_class_ref_annotation(inner.right, RightType) + if RightType in ('', 'void') and LeftType not in ('', 'void'): + return self._is_bare_class_ref_annotation(inner.left, LeftType) return False if isinstance(inner, ast.Subscript): return not (IsRawPtrSubscriptNode(inner) or IsCPtrSubscriptNode(inner))