diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index aff875f..f02db97 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -917,7 +917,9 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy | t.CPtr, # "1fdad1c76fb116bc.free 返回类型无法精确获取" 根因)。 if string.strcmp(attr_nm, "CExport") == 0: return llvmlite.Void(pool) - mapped_ty: llvmlite.LLVMType | t.CPtr = GenApi.map_t_type(pool, attr_nm) + # [阶段2] 统一口径:CTypedef 动态表优先(库 typedef 走正常库分析), + # miss 回退 map_t_type(t/c 库内部特判)。 + mapped_ty: llvmlite.LLVMType | t.CPtr = GenApi.resolve_typedef_or_map(pool, attr_nm, None, None) if mapped_ty is not None: return mapped_ty return None @@ -945,8 +947,8 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy | t.CPtr, bare_enum_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_enum_base_type(seg) if bare_enum_ty is not None: return bare_enum_ty - # 裸 typedef 名(如 VOIDPTR) - mapped_bare: llvmlite.LLVMType | t.CPtr = GenApi.map_t_type(pool, seg) + # 裸 typedef 名(如 VOIDPTR):CTypedef 动态表优先,miss 回退 map_t_type + mapped_bare: llvmlite.LLVMType | t.CPtr = GenApi.resolve_typedef_or_map(pool, seg, None, None) if mapped_bare is not None: return mapped_bare return None diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 7b63556..dbb171e 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -578,6 +578,12 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 对应 TPC 中对 BinOp/BitOr 联合类型的特殊处理 if string.strstr(sz_cls_name, "|") is not None: return llvmlite.const_int64(pool, 8) + # [阶段3] 统一尺寸口径:库 typedef(BYTE/DWORD 等)先经正常 + # 库分析解析(resolve_typedef_or_map → 位宽/8),miss 才走 + # 下方硬编码尺寸表(t/c 核心原语)。 + dyn_sz_c: int = self.Gen.TypeGenResolve.get_type_size_bytes(pool, sz_cls_name, None, None) + if dyn_sz_c > 0: + return llvmlite.const_int64(pool, dyn_sz_c) # 内置类型 sizeof(int=4, str/bytes=8 指针, double=8 等) sz_builtin: int = -1 if string.strcmp(sz_cls_name, "int") == 0: diff --git a/App/lib/core/Gen/Class/ClassGenEnum.vp b/App/lib/core/Gen/Class/ClassGenEnum.vp index 223d5e4..076b232 100644 --- a/App/lib/core/Gen/Class/ClassGenEnum.vp +++ b/App/lib/core/Gen/Class/ClassGenEnum.vp @@ -53,8 +53,9 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # t.State → 默认 i32 if string.strcmp(at.attr, "State") == 0: return llvmlite.Int32(pool) - # 其他 t.CXxx 类型 - ty: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, at.attr) + # 其他 t.CXxx 类型:统一口径(CTypedef 动态表优先,miss 回退 map_t_type) + ty: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_typedef_or_map( + pool, at.attr, imported_modules, from_imports) if ty is not None: return ty return llvmlite.Int32(pool) @@ -66,7 +67,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return llvmlite.Int32(pool) if string.strcmp(nm.id, "State") == 0: return llvmlite.Int32(pool) - ty2: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, nm.id) + ty2: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_typedef_or_map( + pool, nm.id, imported_modules, from_imports) if ty2 is not None: return ty2 return llvmlite.Int32(pool) @@ -531,7 +533,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): VLogger.info(f"registered {class_name} with {field_count} fields, max_size={max_size}", "UNION") return 0 - def _get_annotation_field_size(self, annotation: ast.AST | t.CPtr) -> int: + def _get_annotation_field_size(self, pool: memhub.MemBuddy | t.CPtr, + annotation: ast.AST | t.CPtr) -> int: """计算注解类型的字节大小,用于 REnum 布局计算""" if annotation is None: return 8 @@ -551,6 +554,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): type_name = at.attr if type_name is None: return 8 + # [阶段3] 统一尺寸口径:库 typedef(BYTE/DWORD 等)先经正常库分析解析, + # miss 才走下方硬编码尺寸表(t/c 核心原语)。 + dyn_sz: int = self.Gen.TypeGenResolve.get_type_size_bytes(pool, type_name, None, None) + if dyn_sz > 0: + return dyn_sz # 内置类型 if string.strcmp(type_name, "int") == 0: return 4 @@ -656,7 +664,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 提取字段名 vnm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(vaa.target) # 计算字段大小 - fsize: int = self._get_annotation_field_size(vaa.annotation) + fsize: int = self._get_annotation_field_size(pool, vaa.annotation) if variant_count < 32 and field_idx < 16: # variant_field_sizes[variant_count][field_idx] = fsize offset: t.CSizeT = variant_count * 16 + field_idx diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 66d1ac2..aa4a0a7 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -284,6 +284,12 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if string.strcmp(type_name, "USHORT") == 0: return 1 if string.strcmp(type_name, "UINT") == 0: return 1 if string.strcmp(type_name, "ULONG") == 0: return 1 + # [阶段3] CTypedef 动态表兜底:stdint 别名(DWORD/uint32_t 等)走库定义 + # 展开,按 _annot_str_unsigned 子串规则判断符号性(单一真源)。 + ts_u: str = self.Gen.TypeGenCType.lookup_ctypedef(type_name) + if ts_u is not None and self.Gen.TypeGenCType.CTypedefFound != 0: + if self._annot_str_unsigned(ts_u) != 0: + return 1 return 0 def _annot_str_unsigned(self, annot: str) -> int: """检查类型注解字符串是否引用无符号整型(子串扫描) diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index 5d2b167..a4e8219 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -112,6 +112,20 @@ def map_t_type(pool: memhub.MemBuddy | t.CPtr, type_name: str) -> llvmlite.LLVMT return None +# ---------------- resolve_typedef_or_map(委托 TypeGenResolve.resolve_typedef_or_map) ---------------- +def resolve_typedef_or_map(pool: memhub.MemBuddy | t.CPtr, + name: str, + imported_modules: str, + from_imports: str, + trans: HT.Translator | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr: + """委托到 gen.resolve_typedef_or_map(CTypedef 动态表优先,miss 回退 map_t_type)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.TypeGenResolve.resolve_typedef_or_map(pool, name, imported_modules, from_imports, trans) + return None + + # ---------------- get_current_file(委托 TypeGenResolve.get_current_file) ---------------- def get_current_file() -> str: """委托到 gen.get_current_file(原 Handles 壳)""" diff --git a/App/lib/core/Gen/Type/TypeGenErr.vp b/App/lib/core/Gen/Type/TypeGenErr.vp index 09b2bef..faa5d67 100644 --- a/App/lib/core/Gen/Type/TypeGenErr.vp +++ b/App/lib/core/Gen/Type/TypeGenErr.vp @@ -360,11 +360,12 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if arg is not None and arg.arg is not None: param_ty: llvmlite.LLVMType | t.CPtr = i32_ty if arg.annotation is not None: - # 直接调用 map_t_type 解析 Attribute 注解 + # 统一口径:CTypedef 动态表优先,miss 回退 map_t_type + # (阶段 2:删除 map_t_type 硬编码别名后,BYTE 等靠库 typedef) if arg.annotation.kind() == ast.ASTKind.Attribute: at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation) if at.attr is not None: - resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, at.attr) + resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, None, None) if resolved is not None: param_ty = resolved bits: int = self.get_llvm_type_bits(param_ty) diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index b911906..29bb117 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -582,6 +582,51 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): def get_current_file(self) -> str: """获取当前编译的文件名(供报错归因使用)""" return self.CurrentFile + def resolve_typedef_or_map(self, pool: memhub.MemBuddy | t.CPtr, + name: str, + imported_modules: str, + from_imports: str, + trans: HT.Translator | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr: + """统一口径:CTypedef 动态表优先展开,miss 回退 map_t_type 硬编码 + + 供 resolve_annotation_type 之外的旁路调用点(TypeGenErr/ClassGenEnum/ + VpiReader 等)使用——保证"库 typedef 走正常库分析、t/c 核心走内部特判" + 在所有类型解析路径一致(阶段 1b/2 收敛)。 + """ + if name is None: + return None + if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH: + ts_rt: str = self.Gen.TypeGenCType.lookup_ctypedef(name) + if ts_rt is not None and self.Gen.TypeGenCType.CTypedefFound != 0: + if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, name) == 0: + inner_rt: ast.AST | t.CPtr = self._parse_type_string(pool, ts_rt, ast.ASTCtx.Load) + if inner_rt is not None: + self.Gen.TypeGenCType.CTypedefResolveDepth += 1 + ity_rt: llvmlite.LLVMType | t.CPtr = self.resolve_annotation_type( + pool, inner_rt, imported_modules, from_imports, trans, 1) + self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 + self.Gen.TypeGenCType._ctypedef_pop_visiting() + if ity_rt is not None: + return ity_rt + return self.map_t_type(pool, name) + def get_type_size_bytes(self, pool: memhub.MemBuddy | t.CPtr, + name: str, + imported_modules: str, + from_imports: str) -> int: + """统一尺寸口径(阶段 3):resolve_typedef_or_map → 位宽/8;失败返回 0 + + 供 __sizeof__/REnum 布局等派生表使用——库 typedef(BYTE/DWORD 等)尺寸 + 走正常库分析,消除各派生表对 stdint 别名的硬编码盲区(阶段 3 收敛)。 + """ + if name is None: + return 0 + ty_sz: llvmlite.LLVMType | t.CPtr = self.resolve_typedef_or_map(pool, name, imported_modules, from_imports) + if ty_sz is None: + return 0 + bits_sz: int = self.Gen.TypeGenErr.get_llvm_type_bits(ty_sz) + if bits_sz <= 0: + return 0 + return bits_sz // 8 def map_t_type(self, pool: memhub.MemBuddy | t.CPtr, type_name: str) -> llvmlite.LLVMType | t.CPtr: """将 t.CXxx / c.CXxx 类型名映射到 LLVMType @@ -677,189 +722,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return llvmlite.Int64(pool) # ============================================================ - # stdint.py 大写别名(Win32/TransPyC 风格) + # stdint.vp 大写/定长/小写/指针/C 标准别名(INT/BYTE/DWORD/int8_t/ + # size_t/_Bool 等)已由 stdint.vp CTypedef 声明权威提供(正常库分析, + # 经 resolve_typedef_or_map/resolve_annotation_type 动态表优先展开)。 + # 此处不再硬编码(对齐 INTPTR/UINTPTR 已删范例 L804-807),消除双事实源; + # map_t_type 仅保留 t/c 库核心原语 + 内建小写 float/double。 # ============================================================ - # 整数类型 - elif string.strcmp(type_name, "INT") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "BOOL") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "UINT") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "BYTE") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "WORD") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "DWORD") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "QWORD") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "TCHAR") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "VOID") == 0: - return llvmlite.Void(pool) - elif string.strcmp(type_name, "SHORT") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "USHORT") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "LONGLONG") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "ULONGLONG") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "LONG") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "ULONG") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "WCHAR") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "FLOAT") == 0: - return llvmlite.Float(pool) - elif string.strcmp(type_name, "DOUBLE") == 0: - return llvmlite.Double(pool) # 小写裸名浮点类型(float = t.CFloat = f32, double = t.CDouble = f64) elif string.strcmp(type_name, "float") == 0: return llvmlite.Float(pool) elif string.strcmp(type_name, "double") == 0: return llvmlite.Double(pool) - elif string.strcmp(type_name, "FSIZE_t") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "LBA_t") == 0: - return llvmlite.Int32(pool) - # 定长整数 - elif string.strcmp(type_name, "INT8") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "INT16") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "INT32") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "INT64") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "UINT8") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "UINT16") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "UINT32") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "UINT64") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "CHAR8") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "CHAR16") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "CHAR32") == 0: - return llvmlite.Int32(pool) - # 小写简写 - elif string.strcmp(type_name, "i8") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "i16") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "i32") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "i64") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "u8") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "u16") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "u32") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "u64") == 0: - return llvmlite.Int64(pool) - # size_t 系列 - elif string.strcmp(type_name, "SIZE_T") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "SSIZE_T") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "PTRDIFF_T") == 0: - return llvmlite.Int64(pool) - - # stdint 指针类型(XxxPTR = XxxType | t.CPtr) - # 注:INTPTR/UINTPTR 已由 stdint.vp CTypedef 声明解析(INTPTR = t.CInt|t.CPtr、 - # UINTPTR = UINT|t.CPtr;stdint.vp L6-14 注释:历史命名 = int*/unsigned int* - # 指针,非 C 标准 intptr_t 整数),删除硬编码避免双事实源(stdint 修改定义 - # 时此处不同步)。CTypedef 动态查表(L1377)先于本 map_t_type 兜底执行。 - elif string.strcmp(type_name, "BYTEPTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "CHARLIST") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "SHORTPTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "USHORTPTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "WCHARPTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "CHARPTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "VOIDPTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - # Windows API 跨模块 typedef(win32base.py 中定义) - # HANDLE = VOIDPTR = i8*,LPCSTR = const char* = i8*,LPCWSTR = const wchar_t* = i16* - elif string.strcmp(type_name, "HANDLE") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "LPCSTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "LPCWSTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "INT8PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "INT16PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "INT32PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int32(pool)) - elif string.strcmp(type_name, "INT64PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int64(pool)) - elif string.strcmp(type_name, "UINT8PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "UINT16PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "UINT32PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int32(pool)) - elif string.strcmp(type_name, "UINT64PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int64(pool)) - elif string.strcmp(type_name, "CHAR8PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - elif string.strcmp(type_name, "CHAR16PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int16(pool)) - elif string.strcmp(type_name, "CHAR32PTR") == 0: - return llvmlite.Ptr(pool, llvmlite.Int32(pool)) - - # C 标准 小写 _t 类型 - elif string.strcmp(type_name, "int8_t") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "int16_t") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "int32_t") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "int64_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "uint8_t") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "uint16_t") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "uint32_t") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "uint64_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "size_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "ssize_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "ptrdiff_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "intptr_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "uintptr_t") == 0: - return llvmlite.Int64(pool) - elif string.strcmp(type_name, "wchar_t") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "char8_t") == 0: - return llvmlite.Int8(pool) - elif string.strcmp(type_name, "char16_t") == 0: - return llvmlite.Int16(pool) - elif string.strcmp(type_name, "char32_t") == 0: - return llvmlite.Int32(pool) - elif string.strcmp(type_name, "_Bool") == 0: - return llvmlite.Int8(pool) return None def _is_t_attr(self, node: ast.AST | t.CPtr, attr_name: str, @@ -1499,6 +1372,30 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): mapped_ty_fallback: llvmlite.LLVMType | t.CPtr = self.map_t_type(pool, nm.id) if mapped_ty_fallback is not None: return mapped_ty_fallback + # [阶段1a] from-import 别名反查(正常库分析):from t import CInt as XXX + # 裸名 XXX 不在 struct/CTypedef/map_t_type 任何表,反查原始名后递归解析。 + # 支撑复杂别名链:YYY: t.CTypedef = XXX(typedef 值引用 from-import 别名)。 + if from_imports is not None: + orig_alias: str = self.Gen.ImportsGen.lookup_from_import_original(from_imports, nm.id) + if orig_alias is not None and string.strcmp(orig_alias, nm.id) != 0: + # 内部指针未 null 终止,复制到独立缓冲区(截断于空格/null) + oa_len: t.CSizeT = 0 + while orig_alias[oa_len] != ' ' and orig_alias[oa_len] != '\0': + oa_len += 1 + if oa_len > 0: + oa_buf: str = pool.alloc(oa_len + 1) + if oa_buf is not None: + oa_i: t.CSizeT + for oa_i in range(oa_len): + oa_buf[oa_i] = orig_alias[oa_i] + oa_buf[oa_len] = '\0' + # 用原始名重建节点递归解析(depth 守卫复用 resolve 上限) + orig_node_a: ast.AST | t.CPtr = self._parse_type_string(pool, oa_buf, nm.ctx) + if orig_node_a is not None: + alias_ty: llvmlite.LLVMType | t.CPtr = self.resolve_annotation_type( + pool, orig_node_a, imported_modules, from_imports, trans, depth + 1) + if alias_ty is not None: + return alias_ty return None # Attribute 节点: t.CInt, t.CUInt64T, namespace_defs.PlainStruct 等 @@ -1535,6 +1432,23 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): mod_imp: int = self.Gen.ImportsGen.is_module_imported(imported_modules, val_name.id) if mod_imp == 0: return None + # [阶段1b] 库 typedef 动态表优先(正常库分析):attr 是库声明 + # 的 typedef 名(如 stdint.INT/BYTE)且表已注册 → 递归展开走库 + # 定义(单一真源);miss 再 map_t_type(t/c 库内部特判,如 t.CInt)。 + # 消除双事实源:Attribute 路径不再被 map_t_type 硬编码截胡。 + if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH: + ctypedef_attr: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr) + if ctypedef_attr is not None and self.Gen.TypeGenCType.CTypedefFound != 0: + if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0: + inner_attr: ast.AST | t.CPtr = self._parse_type_string(pool, ctypedef_attr, ast.ASTCtx.Load) + if inner_attr is not None: + self.Gen.TypeGenCType.CTypedefResolveDepth += 1 + inner_ty_attr: llvmlite.LLVMType | t.CPtr = self.resolve_annotation_type( + pool, inner_attr, imported_modules, from_imports, trans, depth + 1) + self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 + self.Gen.TypeGenCType._ctypedef_pop_visiting() + if inner_ty_attr is not None: + return inner_ty_attr # 先尝试内置类型映射(int 等) mapped_ty: llvmlite.LLVMType | t.CPtr = self.map_t_type(pool, at.attr) if mapped_ty is not None: