diff --git a/lib/core/Handles/HandlesTypeMerge.py b/lib/core/Handles/HandlesTypeMerge.py index ae8c0b3..42c8bb5 100644 --- a/lib/core/Handles/HandlesTypeMerge.py +++ b/lib/core/Handles/HandlesTypeMerge.py @@ -114,9 +114,18 @@ class HandlesTypeMerge(BaseHandle): # 查②后 BaseType=CStruct('Constant'),_get_or_create_struct 会按 # `_struct_sha1_map` 拼出 `".Constant"`(BaseGen.py:527-528), # 与声明端/实参同一结构体对象。 + # 但必须排除**枚举类型本身**(`Entry.IsEnum`,如 `class ASTKind(t.CEnum)`): + # _struct_sha1_map 是按 .vpi 里全部 ClassDef 建的,枚举类也在其中;若一并 + # 当结构体,`x: ASTKind` 这类枚举注解会被建成 opaque struct,与 i32 错位 + # (现场:'IntType' object has no attribute 'is_opaque')。 + # 判据分工:Entry.IsEnum ⇒ 枚举类型(走下方 IsEnum 分支,宽度=i32 等); + # 裸名被枚举**成员**占住(Entry.IsEnumMember / 空标记)⇒ 成员不是类型 + # ⇒ 让位给类定义。 + _is_enum_type: bool = isinstance(Entry, CTypeInfo) and Entry.IsEnum _Gen = getattr(self.Trans, 'LlvmGen', None) - if _Gen and (TypeName in _Gen.structs - or TypeName in getattr(_Gen, '_struct_sha1_map', {})): + if _Gen and not _is_enum_type and ( + TypeName in _Gen.structs + or TypeName in getattr(_Gen, '_struct_sha1_map', {})): Result = CTypeInfo() Result.BaseType = t.CStruct(name=TypeName) Result.IsStruct = True diff --git a/lib/core/LLVMCG/BaseGen.py b/lib/core/LLVMCG/BaseGen.py index 50f09fe..5652b37 100644 --- a/lib/core/LLVMCG/BaseGen.py +++ b/lib/core/LLVMCG/BaseGen.py @@ -493,9 +493,16 @@ class BaseGenMixin: # 结构体。否则此处返回 i32 ⇒ 上游 PtrCount=1 叠加后变成 i32*, # 与调用点实参 %".Constant"* 分裂(现场:constant_get_str_val 的 # 形参 i32*)。类型注解语境下枚举**成员**从不是类型,判据只能是"是否有类定义"。 + # 必须排除**枚举类型本身**(`Entry.IsEnum`,如 `class ASTKind(t.CEnum)`): + # _struct_sha1_map 是按 .vpi 里全部 ClassDef 建的,枚举类也在其中 —— + # 若一并当结构体,枚举注解(kind() 返回值等)会被建为 opaque struct, + # 引发 i32 ↔ 结构体错位('IntType' object has no attribute 'is_opaque' 现场)。 + # 判据分工:Entry.IsEnum ⇒ 枚举类型(走下方枚举分支,宽度=i32 等); + # Entry.IsEnumMember(或裸名被成员占住)⇒ 成员,不是类型 ⇒ 让位给类定义。 _known_class_name: bool = ( - clean_name in getattr(self, '_struct_sha1_map', {}) - or clean_name in getattr(self, 'class_sha1_map', {})) + (clean_name in getattr(self, '_struct_sha1_map', {}) + or clean_name in getattr(self, 'class_sha1_map', {})) + and not (Entry and Entry.IsEnum)) if Entry and Entry.IsTypedef: resolved_str: str = self._resolve_typedef(clean_name) if resolved_str != clean_name: