fix(tpc): Name 注解路径的类/枚举同名判据补齐 _struct_sha1_map

a 编译器缺陷:HandlesTypeMerge._GetCTypeInfoInternal 的 ast.Name 分支在「类名与
枚举成员同名」时只查 Gen.structs,漏了 Gen._struct_sha1_map(跨模块类只登记了
类名→模块 sha1、本模块尚未建出结构体)。同文件的 Attribute 分支(L241-269)与
HandlesClassDef._HasClassDefinition、TypeConvert._type_str_to_llvm_base 的
同一判据都是「structs 或 _struct_sha1_map」,Name 路径独缺,属判据分裂。

现场:rawptr[Constant](includes/ast/exprs.vp:59 accessor,class Constant 声明在
同文件更后面)在导入侧解析时,先命中平坦符号表里的枚举成员 Constant: t.State
(ast/base.vp)→ 返回枚举 → 与 t.CPtr 合并后经 _ctype_to_llvm 的 IsEnum 分支
(枚举名未登记 ⇒ 宽度退化为 i32)得 i32*,与调用点实参 %"<exprs_sha1>.Constant"*
分裂 → FuncGen._adjust_args 报「指针隐式转换已禁止」。

补齐后 BaseType=CStruct(Constant),_get_or_create_struct 按 _struct_sha1_map 拼出
"<exprs_sha1>.Constant"(BaseGen.py:527-528),与声明端/实参同一结构体对象。
This commit is contained in:
TermiNexus committed 2026-09-28 19:40:06 +08:00
1 parent 74ccd31c19
commit 61f074ffa4
1 file changed
+19 -3
+19 -3
View File
@@ -97,10 +97,26 @@ class HandlesTypeMerge(BaseHandle):
Result.Name = TypeName Result.Name = TypeName
Result.PtrCount = 1 # REnum 变量默认为指针(和 struct 一致) Result.PtrCount = 1 # REnum 变量默认为指针(和 struct 一致)
return Result return Result
# 类名与枚举成员名冲突时(如 Constant 既是 ASTKind.Constant 枚举成员又是结构体类名), # 类名与枚举成员名冲突时(如 Constant 既是 ASTKind.Constant 枚举成员又是
# 优先检查 Gen.structs:类型注解应解析为结构体而非枚举值 # 结构体类名),类型注解应解析为结构体而非枚举值。判据是"该名**有类定义**",
# 两个来源都要查(与下方 Attribute 分支 L241-269 的判据**同一条规则源**,
# 也与 TypeConvert._type_str_to_llvm_base 的 `type_str in self.structs or
# type_str in self._struct_sha1_map` 守卫同口径):
# ① Gen.structs:本模块已创建的结构体(原判据);
# ② Gen._struct_sha1_map:预扫描登记了"类名 → 模块 sha1"、但本模块尚未
# 建出结构体的类(跨模块 import 的类)。
# 只查①漏②时的现场:`rawptr[Constant]`(includes/ast/exprs.vp:59 的
# accessor,`class Constant` 声明在同文件更后面)在导入侧解析时该名先命中
# 平坦符号表里的枚举成员 `Constant: t.State`(ast/base.vp)→ 走下方
# `Entry.IsEnum` 分支返回枚举 → 与 t.CPtr 合并后经 _ctype_to_llvm 的
# IsEnum 分支(枚举名未登记 ⇒ 宽度退化为 i32)得 **i32\***,与调用点实参
# %"<exprs_sha1>.Constant"* 分裂 → FuncGen._adjust_args fail-fast。
# 查②后 BaseType=CStruct('Constant'),_get_or_create_struct 会按
# `_struct_sha1_map` 拼出 `"<sha1>.Constant"`(BaseGen.py:527-528),
# 与声明端/实参同一结构体对象。
_Gen = getattr(self.Trans, 'LlvmGen', None) _Gen = getattr(self.Trans, 'LlvmGen', None)
if _Gen and TypeName in _Gen.structs: if _Gen and (TypeName in _Gen.structs
or TypeName in getattr(_Gen, '_struct_sha1_map', {})):
Result = CTypeInfo() Result = CTypeInfo()
Result.BaseType = t.CStruct(name=TypeName) Result.BaseType = t.CStruct(name=TypeName)
Result.IsStruct = True Result.IsStruct = True