diff --git a/lib/core/Handles/HandlesAnnAssign.py b/lib/core/Handles/HandlesAnnAssign.py index f6a4ec6..5048d10 100644 --- a/lib/core/Handles/HandlesAnnAssign.py +++ b/lib/core/Handles/HandlesAnnAssign.py @@ -9,7 +9,21 @@ from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo from lib.core.VLogger import get_logger as _vlog from lib.constants.config import mode as _config_mode from lib.includes import t -from lib.core.SymbolUtils import IsListAnnotation, ParseListAnnotation, FindStructNameInAnnotation, AnnotationContainsName, IsCPtrNode +from lib.core.SymbolUtils import IsListAnnotation, ParseListAnnotation, FindStructNameInAnnotation, AnnotationContainsName, IsCPtrNode + + +def _IsGenericTpName(name: str) -> bool: + """判断名称是否为泛型类型参数(单字母大写,如 T/U/V) + + 用于 _is_struct_ptr_union 判定:elem_ptr: T | t.CPtr = t.CPtr(...) + (_list.vp 泛型方法体,T 未解析)时按 8 字节指针槽处理,避免 + var_struct_class 误注册 llvmlite.Value 后 elem_ptr[0] cast 到 Value* + 与函数声明 i8* 不匹配(8fbba llc 报错根因)。标量 T(如 int)退化为 + Ptr(i32) 不命中 _HandleSubscriptLlvm 的 i8 分支,不受此影响。 + """ + if not name: + return False + return len(name) == 1 and name.isalpha() and name.isupper() class AnnAssignHandle(BaseHandle): @@ -496,10 +510,12 @@ class AnnAssignHandle(BaseHandle): and isinstance(Node.annotation.op, ast.BitOr) and ((IsCPtrNode(Node.annotation.left) and isinstance(Node.annotation.right, ast.Name) - and Node.annotation.right.id in Gen.structs) + and (Node.annotation.right.id in Gen.structs + or _IsGenericTpName(Node.annotation.right.id))) or (IsCPtrNode(Node.annotation.right) and isinstance(Node.annotation.left, ast.Name) - and Node.annotation.left.id in Gen.structs)) + and (Node.annotation.left.id in Gen.structs + or _IsGenericTpName(Node.annotation.left.id)))) ) if _is_cptr_assign and _is_struct_ptr_union: Gen.var_ptr_element[VarName] = True diff --git a/lib/core/Handles/HandlesExprAttr.py b/lib/core/Handles/HandlesExprAttr.py index e0b0e6b..a60224b 100644 --- a/lib/core/Handles/HandlesExprAttr.py +++ b/lib/core/Handles/HandlesExprAttr.py @@ -1035,6 +1035,20 @@ class ExprAttrHandle(BaseHandle): return self._load_arr_elem_with_bswap(Gen, ElemPtr, arr_byte_order) else: if isinstance(pointee, ir.IntType) and pointee.width == 8: + # 指针槽变量优先(8fbba 修复):T|t.CPtr 指针槽(elem_ptr 指向 + # 8 字节指针数组,如 _list.vp 泛型方法体)→ i8** load i8*。 + # 必须放在 _infer_element_struct_class 之前——泛型 T 未解析时 + # var_struct_class 误注册 llvmlite.Value,若先推断 elem_class + # 会 cast 到 Value*,与函数声明 i8* 不匹配(llc 报错)。 + if isinstance(Node.value, ast.Name): + _ptr_elem_flag: bool = (getattr(Gen, 'var_ptr_element', {}).get(Node.value.id, False) + or getattr(Gen, 'global_var_ptr_element', {}).get(Node.value.id, False)) + if _ptr_elem_flag: + CastedPtrPtr: Any = Gen.builder.bitcast(ValueVal, ir.PointerType(ir.PointerType(ir.IntType(8))), name="cast_pp_str") + if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64: + IndexVal = Gen.builder.zext(IndexVal, ir.IntType(64), name="zext_pp_str_index") + ElemPtr = Gen.builder.gep(CastedPtrPtr, [IndexVal], name="subscript") + return Gen._load(ElemPtr, name="str_ptr_load") elem_class: str | None = self._infer_element_struct_class(Node.value, Gen) if elem_class and elem_class in Gen.structs: CastedPtr: Any = Gen.builder.bitcast(ValueVal, ir.PointerType(Gen.structs[elem_class]), name=f"cast_{elem_class}_arr") @@ -1047,10 +1061,10 @@ class ExprAttrHandle(BaseHandle): # 指针到 str/bytes 的变量 (BinOp 注解如 str | t.CPtr) # elem_ptr 是 i8* 但实际指向 i8* (字符串指针), elem_ptr[0] 应加载 8 字节 if isinstance(Node.value, ast.Name): - _ptr_elem_flag: bool = (getattr(Gen, 'var_ptr_element', {}).get(Node.value.id, False) - or getattr(Gen, 'global_var_ptr_element', {}).get(Node.value.id, False)) + _ptr_elem_flag = (getattr(Gen, 'var_ptr_element', {}).get(Node.value.id, False) + or getattr(Gen, 'global_var_ptr_element', {}).get(Node.value.id, False)) if _ptr_elem_flag: - CastedPtrPtr: Any = Gen.builder.bitcast(ValueVal, ir.PointerType(ir.PointerType(ir.IntType(8))), name="cast_pp_str") + CastedPtrPtr = Gen.builder.bitcast(ValueVal, ir.PointerType(ir.PointerType(ir.IntType(8))), name="cast_pp_str") if isinstance(IndexVal.type, ir.IntType) and IndexVal.type.width < 64: IndexVal = Gen.builder.zext(IndexVal, ir.IntType(64), name="zext_pp_str_index") ElemPtr = Gen.builder.gep(CastedPtrPtr, [IndexVal], name="subscript")