diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 6397fbc..b23f081 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -1584,7 +1584,11 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, cptr_sub_ty = seg_ty_cs elif string.strcmp(seg_buf, "t.CPtr") == 0 or string.strcmp(seg_buf, "CPtr") == 0: has_cptr = 1 - elif string.strcmp(seg_buf, "t.CVoid") == 0 or string.strcmp(seg_buf, "CVoid") == 0: + elif string.strcmp(seg_buf, "t.CVoid") == 0 or string.strcmp(seg_buf, "CVoid") == 0 \ + or string.strcmp(seg_buf, "void") == 0: + # 裸名 void 是 t.CVoid 的别名(用户 2026-10-01):必须与 CVoid 同处理, + # 否则会走 else 分支取到 first_td=1 → Ptr(Void) 这种非法类型 + # (void* 应为 i8*,由下方 has_cptr 分支统一给出)。 has_cvoid = 1 else: seg_ty: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf) @@ -1618,6 +1622,14 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, if has_cvoid != 0: return i8_ptr_ty if first_ty is not None: + # 解析结果本身即 void(如 `typedef 不透明结构体 = void` 的名字经 typedef 兜底 + # 解析出 void)⇒ 与 t.CPtr 合并即 void* = i8*,与 has_cvoid 分支同结论 + # (否则会拼出非法的 Ptr(void))。 + match first_ty: + case llvmlite.LLVMType.Void(): + return i8_ptr_ty + case _: + pass # 复刻定义侧规则(N12/N13):限定名 / 白名单裸标量 / 已注册结构体 / 可解析的非指针裸 typedef 别名 → 保留 pointee; # 其余(解析失败、裸枚举名、指针别名)→ 联合坍缩为 i8*,与定义侧 resolve_annotation_type 对称(两侧同型即收敛)。 # 指针别名(first_td 不置位,如 VOIDPTR = CVoid|CPtr → i8*):`| t.CPtr` diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 36f1aee..5cac4cd 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -1938,7 +1938,9 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # 小写别名 callable:注解位置等价于 t.Callable(`func: callable = 函数名`)。 elif string.strcmp(type_name, "callable") == 0: return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "CVoid") == 0: + # 裸名 void 是 t.CVoid 的别名(用户 2026-10-01 定):单独出现即 LLVM void; + # `void*`(= `void | t.CPtr`)由下方 BinOp 分支归并为 i8*。 + elif string.strcmp(type_name, "CVoid") == 0 or string.strcmp(type_name, "void") == 0: return llvmlite.Void(pool) # CDefine: 编译期常量定义标记(X: t.CDefine = 64),底层为 32 位有符号整数 # (对齐 TPC t.CDefine Size=32 IsSigned=True;超大值由 DefineValue 路径升 i64)。 @@ -2079,8 +2081,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): return 1 if node is not None and node.kind() == ast.ASTKind.Name: nm: ast.Name* = ast.Name*(node) - if nm.id is not None and string.strcmp(nm.id, "CVoid") == 0: - return 1 + # 裸名 CVoid(from t import CVoid)与内置别名 void(无需 import)同义 + if nm.id is not None: + if string.strcmp(nm.id, "CVoid") == 0 or string.strcmp(nm.id, "void") == 0: + return 1 return 0 def annotation_to_str(self, annot: ast.AST*) -> str: """将类型注解 AST 转换为可读字符串,返回 None=无法提取 @@ -3101,12 +3105,24 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): other_is_cvoid = 1 elif other_node.kind() == ast.ASTKind.Name: onm2: ast.Name* = ast.Name*(other_node) - if onm2.id is not None and string.strcmp(onm2.id, "CVoid") == 0: - if self.Gen.ImportsGen.is_module_imported(imported_modules, "t") != 0: + if onm2.id is not None: + if string.strcmp(onm2.id, "CVoid") == 0: + if self.Gen.ImportsGen.is_module_imported(imported_modules, "t") != 0: + other_is_cvoid = 1 + elif string.strcmp(onm2.id, "void") == 0: + # 内置别名 void:t.CVoid 同义,无需 import t other_is_cvoid = 1 if other_is_cvoid != 0: return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, other_node, imported_modules, from_imports, trans, depth + 1) + other_ty: llvmlite.LLVMType* = self.resolve_annotation_type(pool, other_node, imported_modules, from_imports, trans, depth + 1) + # 解析结果本身即 void(如 `typedef 不透明结构体 = void` 的那个名字, + # 或经 typedef 兜底解析出的 void)⇒ 与 CPtr 合并即 void* = i8*, + # 与上方 other_is_cvoid 分支同一结论(否则会拼出非法的 Ptr(void))。 + match other_ty: + case llvmlite.LLVMType.Void(): + return llvmlite.Ptr(pool, llvmlite.Int8(pool)) + case _: + pass # 仅裸名(Name)场景验证解析结果必须是已注册 struct: # 损坏节点可能解析出基础类型垃圾(如 Int8 → Ptr(i8))。 # Attribute 场景(Module.Class / t.XXX)resolve 结果直接可用