fix(compiler): 裸类形参按引用传参 + 同名类优先本模块 + 裸名泛型构造/类型参数转换
- 裸类形参(方法+函数)解析为 Ptr(struct),修复 GSList[T].append 按值传参悬垂(G5 Test4 head.Value 读到垃圾) - resolve_annotation_type 裸类名优先 find_struct_by_module 命中本模块,避免跨模块同名类(main.vp G5Node vs g5container.vp)类型混用 - translate_call 新增裸名泛型类模板构造:Box(42)→从实参推断→特化→构造(GenericTest Test4/5/10、GenericTest2 Stack/Range 等) - 类型转换路径先 resolve_generic_type_name:类特化/泛型函数中的 T(x) 解析为 int/str/bool/double 转换 - 泛型函数翻译时设泛型上下文 T→int(TPV 泛型函数按普通 i32 函数编译,退出作用域前清除)
This commit is contained in:
1 parent
60493d6ae5
commit
e0303c46f6
4 files changed
+145
-10
No files matched your search
@@ -3618,7 +3618,14 @@ def _translate_method(trans: HT.Translator | t.CPtr,
|
|||||||
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||||
pool, arg.annotation, imported_modules, from_imports, trans)
|
pool, arg.annotation, imported_modules, from_imports, trans)
|
||||||
if resolved is not None:
|
if resolved is not None:
|
||||||
param_ty = resolved
|
# 裸类形参 → Ptr(struct):按"对象即指针"引用传参。
|
||||||
|
# 若按 struct 值传参,self.Head = node 会取局部拷贝地址
|
||||||
|
# (append 返回后悬垂,G5 Test4 head.Value 读到垃圾)。
|
||||||
|
match resolved:
|
||||||
|
case llvmlite.LLVMType.Struct(_, _, _):
|
||||||
|
param_ty = llvmlite.Ptr(pool, resolved)
|
||||||
|
case _:
|
||||||
|
param_ty = resolved
|
||||||
pname: t.CChar | t.CPtr = pool.alloc(32)
|
pname: t.CChar | t.CPtr = pool.alloc(32)
|
||||||
if pname is not None:
|
if pname is not None:
|
||||||
viperlib.snprintf(pname, 32, "%%%s", arg.arg)
|
viperlib.snprintf(pname, 32, "%%%s", arg.arg)
|
||||||
@@ -3683,7 +3690,12 @@ def _translate_method(trans: HT.Translator | t.CPtr,
|
|||||||
resolved2: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
resolved2: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||||
pool, arg2.annotation, imported_modules, from_imports, trans)
|
pool, arg2.annotation, imported_modules, from_imports, trans)
|
||||||
if resolved2 is not None:
|
if resolved2 is not None:
|
||||||
param_ty2 = resolved2
|
# 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针)
|
||||||
|
match resolved2:
|
||||||
|
case llvmlite.LLVMType.Struct(_, _, _):
|
||||||
|
param_ty2 = llvmlite.Ptr(pool, resolved2)
|
||||||
|
case _:
|
||||||
|
param_ty2 = resolved2
|
||||||
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, param_ty2)
|
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, param_ty2)
|
||||||
if alloca is not None:
|
if alloca is not None:
|
||||||
HandlesVar.define_var(trans.SymTab, arg2.arg, alloca)
|
HandlesVar.define_var(trans.SymTab, arg2.arg, alloca)
|
||||||
|
|||||||
@@ -4532,6 +4532,46 @@ def _extract_type_args_from_slice(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
# 走裸名路径会被 _lookup_mod_sha1 的 star import 回退误导,用错误的 SHA1
|
# 走裸名路径会被 _lookup_mod_sha1 的 star import 回退误导,用错误的 SHA1
|
||||||
# 且缺少 __new__ 方法名后缀,导致链接报 undefined reference。
|
# 且缺少 __new__ 方法名后缀,导致链接报 undefined reference。
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
def _infer_generic_ctor_type_arg(pool: memhub.MemBuddy | t.CPtr,
|
||||||
|
arg_node: ast.AST | t.CPtr) -> str:
|
||||||
|
"""从构造实参 AST 推断泛型类型实参名;无法推断时默认 "int"(与 TPC 一致)
|
||||||
|
|
||||||
|
裸名泛型类构造(Box(42) → Box[int])需要从实参推断类型实参。
|
||||||
|
对应 TPC _HandleGenericClassNewLlvm 的推断逻辑(常量/类型转换调用)。
|
||||||
|
注意:本函数仅做 AST 静态推断,不发射 IR(避免重复翻译实参)。
|
||||||
|
"""
|
||||||
|
if pool is None or arg_node is None:
|
||||||
|
return "int"
|
||||||
|
k: int = arg_node.kind()
|
||||||
|
# 常量: 42→int, 3.14→double, "abc"→str
|
||||||
|
if k == ast.ASTKind.Constant:
|
||||||
|
cn: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(arg_node)
|
||||||
|
if cn.const_kind == ast.CONST_FLOAT:
|
||||||
|
return "double"
|
||||||
|
if cn.const_kind == ast.CONST_STR:
|
||||||
|
return "str"
|
||||||
|
return "int"
|
||||||
|
# 类型转换调用: int(...)/float(...)/t.CInt(...)/t.CDouble(...)
|
||||||
|
if k == ast.ASTKind.Call:
|
||||||
|
cl_f: ast.Call | t.CPtr = (ast.Call | t.CPtr)(arg_node)
|
||||||
|
if cl_f.func is not None:
|
||||||
|
if cl_f.func.kind() == ast.ASTKind.Name:
|
||||||
|
fn_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(cl_f.func)
|
||||||
|
if fn_nm.id is not None:
|
||||||
|
if string.strcmp(fn_nm.id, "float") == 0:
|
||||||
|
return "double"
|
||||||
|
if string.strcmp(fn_nm.id, "int") == 0:
|
||||||
|
return "int"
|
||||||
|
elif cl_f.func.kind() == ast.ASTKind.Attribute:
|
||||||
|
fn_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl_f.func)
|
||||||
|
if fn_at.attr is not None:
|
||||||
|
if string.strstr(fn_at.attr, "Float") is not None or string.strstr(fn_at.attr, "Double") is not None:
|
||||||
|
return "double"
|
||||||
|
if string.strstr(fn_at.attr, "Int") is not None or string.strstr(fn_at.attr, "UInt") is not None or string.strstr(fn_at.attr, "Char") is not None or string.strstr(fn_at.attr, "Short") is not None or string.strstr(fn_at.attr, "Long") is not None:
|
||||||
|
return "int"
|
||||||
|
return "int"
|
||||||
|
|
||||||
|
|
||||||
def _translate_generic_ctor_call(pool: memhub.MemBuddy | t.CPtr,
|
def _translate_generic_ctor_call(pool: memhub.MemBuddy | t.CPtr,
|
||||||
builder: llvmlite.IRBuilder | t.CPtr,
|
builder: llvmlite.IRBuilder | t.CPtr,
|
||||||
mod: llvmlite.LLVMModule | t.CPtr,
|
mod: llvmlite.LLVMModule | t.CPtr,
|
||||||
@@ -4731,8 +4771,12 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
# 等价于 (t.CChar | t.CPtr)(x) / (t.CInt32T)(x)
|
# 等价于 (t.CChar | t.CPtr)(x) / (t.CInt32T)(x)
|
||||||
# 单参数:str(val) → bitcast val to i8*
|
# 单参数:str(val) → bitcast val to i8*
|
||||||
# int(val) → trunc/sext val to i32
|
# int(val) → trunc/sext val to i32
|
||||||
|
# 泛型类型参数: 类特化/泛型函数上下文中的 T(x) 先解析 T 为具体类型名
|
||||||
|
# (如 "int")再按内建强转处理(Box[int].__init__ 的 self.value = T(v)、
|
||||||
|
# combine[T1,T2] 的 T1(b) 依赖此路径)
|
||||||
if func_name is not None and can == 1:
|
if func_name is not None and can == 1:
|
||||||
if string.strcmp(func_name, "str") == 0 or string.strcmp(func_name, "bytes") == 0:
|
cast_fn_name: str = HandlesType.resolve_generic_type_name(func_name)
|
||||||
|
if string.strcmp(cast_fn_name, "str") == 0 or string.strcmp(cast_fn_name, "bytes") == 0:
|
||||||
# str(x) / bytes(x) → i8* (bitcast)
|
# str(x) / bytes(x) → i8* (bitcast)
|
||||||
cast_arg: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
cast_arg: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
||||||
@@ -4740,7 +4784,7 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
i8_ptr_ty_builtin: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
i8_ptr_ty_builtin: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||||
return _translate_t_type_cast(pool, builder, cast_arg, i8_ptr_ty_builtin)
|
return _translate_t_type_cast(pool, builder, cast_arg, i8_ptr_ty_builtin)
|
||||||
return None
|
return None
|
||||||
elif string.strcmp(func_name, "int") == 0:
|
elif string.strcmp(cast_fn_name, "int") == 0:
|
||||||
# int(x) → i32
|
# int(x) → i32
|
||||||
cast_arg_int: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
cast_arg_int: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
||||||
@@ -4748,7 +4792,7 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
i32_ty_builtin: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
i32_ty_builtin: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
||||||
return _translate_t_type_cast(pool, builder, cast_arg_int, i32_ty_builtin)
|
return _translate_t_type_cast(pool, builder, cast_arg_int, i32_ty_builtin)
|
||||||
return None
|
return None
|
||||||
elif string.strcmp(func_name, "bool") == 0:
|
elif string.strcmp(cast_fn_name, "bool") == 0:
|
||||||
# bool(x) → i1(严格 != 0 归一化)
|
# bool(x) → i1(严格 != 0 归一化)
|
||||||
# 整数: icmp ne x, 0 → i1
|
# 整数: icmp ne x, 0 → i1
|
||||||
# 浮点: fcmp one x, 0.0 → i1
|
# 浮点: fcmp one x, 0.0 → i1
|
||||||
@@ -4823,8 +4867,17 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
# 裸名 typedef 调用: BYTEPTR(ptr1), HANDLE(val), CHARPTR(str) 等
|
# 裸名 typedef 调用: BYTEPTR(ptr1), HANDLE(val), CHARPTR(str) 等
|
||||||
# 用户通过 `from stdint import *` 导入 typedef 后,可直接用裸名做类型转换
|
# 用户通过 `from stdint import *` 导入 typedef 后,可直接用裸名做类型转换
|
||||||
# map_t_type 包含所有内置 typedef 名称(BYTEPTR/HANDLE/LPCSTR/size_t 等)
|
# map_t_type 包含所有内置 typedef 名称(BYTEPTR/HANDLE/LPCSTR/size_t 等)
|
||||||
|
# 泛型类型参数转换: 泛型上下文(类特化/泛型函数)中 T(x) → 先解析 T 为具体
|
||||||
|
# 类型名(如 "int")再走 map_t_type(Box[int].__init__ 的 self.value = T(v)、
|
||||||
|
# combine[T1,T2] 的 T1(b) 依赖此路径)
|
||||||
if cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
|
if cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
|
||||||
bare_ty: llvmlite.LLVMType | t.CPtr = HandlesType.map_t_type(pool, func_name)
|
bare_fn_name: str = HandlesType.resolve_generic_type_name(func_name)
|
||||||
|
bare_ty: llvmlite.LLVMType | t.CPtr = None
|
||||||
|
# 泛型上下文解析出的内建名(如 T→"double"):map_t_type 只认 t.CDouble
|
||||||
|
if string.strcmp(bare_fn_name, "double") == 0 or string.strcmp(bare_fn_name, "float") == 0:
|
||||||
|
bare_ty = llvmlite.Double(pool)
|
||||||
|
else:
|
||||||
|
bare_ty = HandlesType.map_t_type(pool, bare_fn_name)
|
||||||
if bare_ty is not None and can == 1:
|
if bare_ty is not None and can == 1:
|
||||||
bare_arg_node: ast.AST | t.CPtr = cargs.get(0)
|
bare_arg_node: ast.AST | t.CPtr = cargs.get(0)
|
||||||
if bare_arg_node is not None:
|
if bare_arg_node is not None:
|
||||||
@@ -5403,6 +5456,31 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
return _translate_struct_ctor(
|
return _translate_struct_ctor(
|
||||||
pool, builder, mod, struct_ty, func_name, cargs, can, trans)
|
pool, builder, mod, struct_ty, func_name, cargs, can, trans)
|
||||||
|
|
||||||
|
# 裸名泛型类模板构造: Box(42) → 从实参推断类型实参 → 特化 → 构造
|
||||||
|
# (TPC 参考: _HandleGenericClassNewLlvm;GenericTest Test4 Box(42)/Test5
|
||||||
|
# Pair(10,20)/Test10 Counter(0) 依赖此路径。显式类型实参 list[int](mb)
|
||||||
|
# 走 translate_call 上方的 Subscript 分支,此处处理裸名 + 推断。)
|
||||||
|
if struct_ty is None and gen_ctor_entry is None and trans is not None:
|
||||||
|
if cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
|
||||||
|
template_cd_bare: ast.ClassDef | t.CPtr = HandlesClassDef._find_generic_template(func_name)
|
||||||
|
if template_cd_bare is not None and template_cd_bare.type_params is not None:
|
||||||
|
tp_bare: list[str] | t.CPtr = template_cd_bare.type_params
|
||||||
|
tp_count_bare: t.CSizeT = tp_bare.__len__()
|
||||||
|
if tp_count_bare > 0:
|
||||||
|
inferred_args_bare: list[str] | t.CPtr = list[str](pool, 8)
|
||||||
|
if inferred_args_bare is not None:
|
||||||
|
tpi_bare: t.CSizeT = 0
|
||||||
|
for tpi_bare in range(tp_count_bare):
|
||||||
|
ta_bare: str = "int"
|
||||||
|
if tpi_bare < can:
|
||||||
|
ta_bare = _infer_generic_ctor_type_arg(pool, cargs.get(tpi_bare))
|
||||||
|
inferred_args_bare.append(ta_bare)
|
||||||
|
spec_name_bare: str = HandlesClassDef._specialize_generic_class(
|
||||||
|
trans, func_name, inferred_args_bare)
|
||||||
|
if spec_name_bare is not None:
|
||||||
|
return _translate_generic_ctor_call(
|
||||||
|
pool, builder, mod, spec_name_bare, cl, trans)
|
||||||
|
|
||||||
# REnum 变体构造检测: ClassName.VariantName(args...)
|
# REnum 变体构造检测: ClassName.VariantName(args...)
|
||||||
# 如 LLVMType.Int(1) → 构造 LLVMType 的 Int 变体
|
# 如 LLVMType.Int(1) → 构造 LLVMType 的 Int 变体
|
||||||
# 必须在跨模块调用查找之前,否则 ClassName 会被误判为模块名
|
# 必须在跨模块调用查找之前,否则 ClassName 会被误判为模块名
|
||||||
|
|||||||
@@ -401,7 +401,12 @@ def forward_declare_functions(trans: HT.Translator | t.CPtr,
|
|||||||
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||||
pool, arg.annotation, imported_modules, from_imports, trans)
|
pool, arg.annotation, imported_modules, from_imports, trans)
|
||||||
if resolved is not None:
|
if resolved is not None:
|
||||||
param_ty = resolved
|
# 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致)
|
||||||
|
match resolved:
|
||||||
|
case llvmlite.LLVMType.Struct(_, _, _):
|
||||||
|
param_ty = llvmlite.Ptr(pool, resolved)
|
||||||
|
case _:
|
||||||
|
param_ty = resolved
|
||||||
pname: t.CChar | t.CPtr = pool.alloc(32)
|
pname: t.CChar | t.CPtr = pool.alloc(32)
|
||||||
if pname is not None:
|
if pname is not None:
|
||||||
viperlib.snprintf(pname, 32, "%%%s", arg.arg)
|
viperlib.snprintf(pname, 32, "%%%s", arg.arg)
|
||||||
@@ -523,7 +528,12 @@ def translate_function_def(trans: HT.Translator | t.CPtr,
|
|||||||
resolved_e: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
resolved_e: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||||
pool, arg_e.annotation, imported_modules, from_imports, trans)
|
pool, arg_e.annotation, imported_modules, from_imports, trans)
|
||||||
if resolved_e is not None:
|
if resolved_e is not None:
|
||||||
param_ty_e = resolved_e
|
# 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致)
|
||||||
|
match resolved_e:
|
||||||
|
case llvmlite.LLVMType.Struct(_, _, _):
|
||||||
|
param_ty_e = llvmlite.Ptr(pool, resolved_e)
|
||||||
|
case _:
|
||||||
|
param_ty_e = resolved_e
|
||||||
pname_e: t.CChar | t.CPtr = pool.alloc(32)
|
pname_e: t.CChar | t.CPtr = pool.alloc(32)
|
||||||
if pname_e is not None:
|
if pname_e is not None:
|
||||||
viperlib.snprintf(pname_e, 32, "%%%s", arg_e.arg)
|
viperlib.snprintf(pname_e, 32, "%%%s", arg_e.arg)
|
||||||
@@ -605,7 +615,12 @@ def translate_function_def(trans: HT.Translator | t.CPtr,
|
|||||||
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
resolved: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||||
pool, arg.annotation, imported_modules, from_imports, trans)
|
pool, arg.annotation, imported_modules, from_imports, trans)
|
||||||
if resolved is not None:
|
if resolved is not None:
|
||||||
param_ty = resolved
|
# 裸类形参 → Ptr(struct)(对象即指针,与方法形参一致)
|
||||||
|
match resolved:
|
||||||
|
case llvmlite.LLVMType.Struct(_, _, _):
|
||||||
|
param_ty = llvmlite.Ptr(pool, resolved)
|
||||||
|
case _:
|
||||||
|
param_ty = resolved
|
||||||
pname: t.CChar | t.CPtr = pool.alloc(32)
|
pname: t.CChar | t.CPtr = pool.alloc(32)
|
||||||
if pname is not None:
|
if pname is not None:
|
||||||
viperlib.snprintf(pname, 32, "%%%s", arg.arg)
|
viperlib.snprintf(pname, 32, "%%%s", arg.arg)
|
||||||
@@ -632,6 +647,21 @@ def translate_function_def(trans: HT.Translator | t.CPtr,
|
|||||||
# 进入函数作用域(嵌套符号表)
|
# 进入函数作用域(嵌套符号表)
|
||||||
HandlesVar.enter_scope(trans.SymTab, SCOPE_FUNCTION)
|
HandlesVar.enter_scope(trans.SymTab, SCOPE_FUNCTION)
|
||||||
|
|
||||||
|
# PEP 695 泛型函数: def f[T](...) — 设置泛型上下文,类型参数映射到 "int" 兜底。
|
||||||
|
# TPV 无泛型函数特化机制(类泛型走 _specialize_generic_class),泛型函数按普通
|
||||||
|
# 函数编译;设置上下文使参数注解 T / 方法体中的 T(x) 转换可解析为 int。
|
||||||
|
# (注意与类特化的 set_generic_context 一样是全局状态,需在退出作用域前清除。)
|
||||||
|
tp_names_fn: list[str] | t.CPtr = None
|
||||||
|
if fd.type_params is not None:
|
||||||
|
tp_names_fn = fd.type_params
|
||||||
|
tp_args_fn: list[str] | t.CPtr = list[str](pool, 8)
|
||||||
|
if tp_args_fn is not None:
|
||||||
|
tpn_fn: t.CSizeT = fd.type_params.__len__()
|
||||||
|
tpi_fn: t.CSizeT = 0
|
||||||
|
for tpi_fn in range(tpn_fn):
|
||||||
|
tp_args_fn.append("int")
|
||||||
|
HandlesType.set_generic_context(tp_names_fn, tp_args_fn)
|
||||||
|
|
||||||
# 为参数创建 alloca
|
# 为参数创建 alloca
|
||||||
if args_node is not None:
|
if args_node is not None:
|
||||||
ags2: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
|
ags2: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
|
||||||
@@ -650,7 +680,12 @@ def translate_function_def(trans: HT.Translator | t.CPtr,
|
|||||||
resolved2: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
resolved2: llvmlite.LLVMType | t.CPtr = HandlesType.resolve_annotation_type(
|
||||||
pool, arg2.annotation, imported_modules, from_imports, trans)
|
pool, arg2.annotation, imported_modules, from_imports, trans)
|
||||||
if resolved2 is not None:
|
if resolved2 is not None:
|
||||||
param_ty2 = resolved2
|
# 与 add_param 保持一致:裸类形参 → Ptr(struct)(对象即指针)
|
||||||
|
match resolved2:
|
||||||
|
case llvmlite.LLVMType.Struct(_, _, _):
|
||||||
|
param_ty2 = llvmlite.Ptr(pool, resolved2)
|
||||||
|
case _:
|
||||||
|
param_ty2 = resolved2
|
||||||
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, param_ty2)
|
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, param_ty2)
|
||||||
if alloca is not None:
|
if alloca is not None:
|
||||||
HandlesVar.define_var(trans.SymTab, arg2.arg, alloca)
|
HandlesVar.define_var(trans.SymTab, arg2.arg, alloca)
|
||||||
@@ -765,6 +800,8 @@ def translate_function_def(trans: HT.Translator | t.CPtr,
|
|||||||
llvmlite.build_ret(func_builder, _zero_val)
|
llvmlite.build_ret(func_builder, _zero_val)
|
||||||
|
|
||||||
# 恢复模块级作用域(退出函数作用域)
|
# 恢复模块级作用域(退出函数作用域)
|
||||||
|
if tp_names_fn is not None:
|
||||||
|
HandlesType.clear_generic_context()
|
||||||
HandlesVar.exit_scope(trans.SymTab)
|
HandlesVar.exit_scope(trans.SymTab)
|
||||||
trans._cur_func = old_func
|
trans._cur_func = old_func
|
||||||
trans._cur_builder = old_builder
|
trans._cur_builder = old_builder
|
||||||
|
|||||||
@@ -1582,6 +1582,14 @@ def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr,
|
|||||||
# class 名称: 查找已注册的 StructType,返回 StructType 本身(不包装 Ptr)
|
# class 名称: 查找已注册的 StructType,返回 StructType 本身(不包装 Ptr)
|
||||||
# 这样 build_alloca 会分配结构体大小的空间,alloca 返回 struct_ty*
|
# 这样 build_alloca 会分配结构体大小的空间,alloca 返回 struct_ty*
|
||||||
# 命名空间隔离:严格模式下仅解析可见的结构体
|
# 命名空间隔离:严格模式下仅解析可见的结构体
|
||||||
|
# 跨模块同名类优先:当前模块自身定义了同名类时,用 find_struct_by_module
|
||||||
|
# 命中本模块的类(如 main.vp 的 G5Node 不再被 g5container.vp 预注册的
|
||||||
|
# G5Node 顶掉,避免 alloca 用本模块类型、load 用他模块类型的混用)。
|
||||||
|
# 本模块未定义时回退按裸名全局查找(import 来的类走此路径)。
|
||||||
|
if trans is not None and trans.ModuleSha1 is not None:
|
||||||
|
own_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct_by_module(nm.id, trans.ModuleSha1)
|
||||||
|
if own_entry is not None and own_entry.Ty is not None:
|
||||||
|
return own_entry.Ty
|
||||||
if HandlesStruct.is_struct_visible(nm.id) != 0:
|
if HandlesStruct.is_struct_visible(nm.id) != 0:
|
||||||
struct_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type(nm.id)
|
struct_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type(nm.id)
|
||||||
if struct_ty is not None:
|
if struct_ty is not None:
|
||||||
|
|||||||
Reference in new issue
Block a user