diff --git a/lib/core/Handles/HandlesTypeMerge.py b/lib/core/Handles/HandlesTypeMerge.py index 42c8bb5..8a94d4f 100644 --- a/lib/core/Handles/HandlesTypeMerge.py +++ b/lib/core/Handles/HandlesTypeMerge.py @@ -114,14 +114,19 @@ class HandlesTypeMerge(BaseHandle): # 查②后 BaseType=CStruct('Constant'),_get_or_create_struct 会按 # `_struct_sha1_map` 拼出 `".Constant"`(BaseGen.py:527-528), # 与声明端/实参同一结构体对象。 - # 但必须排除**枚举类型本身**(`Entry.IsEnum`,如 `class ASTKind(t.CEnum)`): + # 但必须排除**枚举类型本身**(如 `class ASTKind(t.CEnum)` 的注解 `x: ASTKind`): # _struct_sha1_map 是按 .vpi 里全部 ClassDef 建的,枚举类也在其中;若一并 - # 当结构体,`x: ASTKind` 这类枚举注解会被建成 opaque struct,与 i32 错位 + # 当结构体,枚举注解会被建成 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 + # 判据必须按 **IsEnumMember** 区分(现场实测):枚举**成员**条目的标志组合是 + # IsEnum=True + IsEnumMember=True + BaseType=CEnum + # (即成员的 IsEnum 也被置真),只判 IsEnum 会把成员误当枚举类型 ⇒ 落 i32*; + # 而枚举**类型**条目是 IsEnum=True + IsEnumMember=False。 + # 故:枚举类型 = IsEnum and not IsEnumMember ⇒ 走下方 IsEnum 分支; + # 成员(IsEnumMember)⇒ 不是类型 ⇒ 让位给类定义。 + _is_enum_type: bool = ( + isinstance(Entry, CTypeInfo) and Entry.IsEnum + and not getattr(Entry, 'IsEnumMember', False)) _Gen = getattr(self.Trans, 'LlvmGen', None) if _Gen and not _is_enum_type and ( TypeName in _Gen.structs diff --git a/lib/core/LLVMCG/BaseGen.py b/lib/core/LLVMCG/BaseGen.py index 5304eae..26d2c15 100644 --- a/lib/core/LLVMCG/BaseGen.py +++ b/lib/core/LLVMCG/BaseGen.py @@ -493,16 +493,19 @@ 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(或裸名被成员占住)⇒ 成员,不是类型 ⇒ 让位给类定义。 + # 必须排除**枚举类型本身**(如 `class ASTKind(t.CEnum)`):_struct_sha1_map + # 是按 .vpi 里全部 ClassDef 建的,枚举类也在其中 —— 若一并当结构体,枚举 + # 注解(kind() 返回值等)会被建为 opaque struct,引发 i32 ↔ 结构体错位 + # ('IntType' object has no attribute 'is_opaque' 现场)。 + # 判据必须按 **IsEnumMember** 区分(现场实测标志组合): + # 枚举**成员** = IsEnum=True + IsEnumMember=True + BaseType=CEnum + # 枚举**类型** = IsEnum=True + IsEnumMember=False + # 只判 IsEnum 会把成员误当枚举类型 ⇒ 返回 i32 ⇒ 上游 PtrCount=1 ⇒ i32*。 _known_class_name: bool = ( (clean_name in getattr(self, '_struct_sha1_map', {}) or clean_name in getattr(self, 'class_sha1_map', {})) - and not (Entry and Entry.IsEnum)) + and not (Entry and Entry.IsEnum + and not getattr(Entry, 'IsEnumMember', False))) if Entry and Entry.IsTypedef: resolved_str: str = self._resolve_typedef(clean_name) if resolved_str != clean_name: