fix(class): __before_init__ 定义时复用同名前向声明,消除同模块 declare+define
本类方法体内构造自身(如 Vec2.__add__ 里 return Vec2(...))时,构造路径先经 _call_method_on_ptr → _ensure_method_declare 在本模块建好同名 __before_init__ 前向声明(IsDeclared=1);随后 _generate_before_init 又 create_function 追加一条同名 define,使同一模块 IR 同时出现 declare 与 define → llc 报 invalid redefinition of function(OopInheritTest 根因;④ 改用 full.ll 直喂 llc 后不再被旧 BuildCombinedIR 去重掩盖)。改为按名复用该前向声明(命名首参 %self、校准类型、清 IsDeclared 转 define),与 _generate_method/FuncGenDef 同构。
This commit is contained in:
1 parent
4c114d8875
commit
67667b10db
1 file changed
+32
-5
@@ -1140,9 +1140,25 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
|
||||
mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, full_name)
|
||||
|
||||
# 创建函数
|
||||
func: llvmlite.Function* = llvmlite.create_function(pool, mod, mangled_name, void_ty)
|
||||
if func is None: return 0
|
||||
# 创建/复用 LLVM 函数。
|
||||
# 复用场景:本类方法体内构造自身时(如 Vec2.__add__ 里 `return Vec2(...)`),
|
||||
# CallGenCtor._translate_struct_ctor 先经 CallGenCall._call_method_on_ptr →
|
||||
# CallGenBase._ensure_method_declare 在本模块建好同名 __before_init__ 前向声明
|
||||
# (IsDeclared=1,形参无名且无函数体)。此刻本 define 尚未生成,若此处再
|
||||
# create_function 追加一条同名 define,同模块内 declare+define 并存 → llc
|
||||
# "invalid redefinition of function"。故按名复用该声明,清零 IsDeclared 转
|
||||
# define——与 _generate_method(本文件 L686-705)、FuncGenDef(L552-555)同构。
|
||||
bi_func: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name)
|
||||
bi_decl_reuse: int = 0
|
||||
if bi_func is not None:
|
||||
if bi_func.IsDeclared == 0:
|
||||
# 同名函数体已发射:禁止重复发射(duplicate symbol)
|
||||
return 0
|
||||
bi_decl_reuse = 1
|
||||
else:
|
||||
bi_func = llvmlite.create_function(pool, mod, mangled_name, void_ty)
|
||||
if bi_func is None: return 0
|
||||
func: llvmlite.Function* = bi_func
|
||||
|
||||
# 注册到函数表
|
||||
max_funcs: int = 1024
|
||||
@@ -1150,8 +1166,19 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if rc_add == 0:
|
||||
trans._func_count = func_count + 1
|
||||
|
||||
# 添加 self 参数
|
||||
llvmlite.add_param(pool, func, self_ptr_ty, "%self")
|
||||
if bi_decl_reuse != 0:
|
||||
# 复用前向声明:self 参数已由 _ensure_method_declare 添加(无名),
|
||||
# 此处只需命名首参 %self 并校准为定义侧类型——函数体以 %self 引用它,
|
||||
# 无名形参会让函数体的 %self 无定义(llvmlite FunctionPrint 仅在
|
||||
# Param.Name 非空时打印参数名)。
|
||||
bi_first_param: llvmlite.Param* = llvmlite.function_get_param_head(func)
|
||||
if bi_first_param is not None:
|
||||
bi_first_param.Ty = self_ptr_ty
|
||||
bi_first_param.Name = "%self"
|
||||
func.IsDeclared = 0
|
||||
else:
|
||||
# 添加 self 参数
|
||||
llvmlite.add_param(pool, func, self_ptr_ty, "%self")
|
||||
|
||||
# 参数添加完成,补全全局函数表的 Spec
|
||||
rc_ut: int = self.Gen.CallGenLeafKit.update_global_func_spec(full_name, func)
|
||||
|
||||
Reference in new issue
Block a user