diff --git a/App/lib/core/Gen/Expr/ExprGenFstr.vp b/App/lib/core/Gen/Expr/ExprGenFstr.vp index 94e9340..6415216 100644 --- a/App/lib/core/Gen/Expr/ExprGenFstr.vp +++ b/App/lib/core/Gen/Expr/ExprGenFstr.vp @@ -183,6 +183,19 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): zero_i32: llvmlite.Value* = llvmlite.const_int32(pool, 0) buf_ptr: llvmlite.Value* = llvmlite.build_gep_array(builder, buf_ty, i8_ty, buf_alloca, zero_i32) if buf_ptr is None: return None + # f-string 降级为 snprintf 调用,而 snprintf 的声明在 includes/stdio.vp:7 + # (`extern def snprintf(buf, size, fmt, *args) -> int`)。源文件若未 + # import 任何声明它的模块,当前模块就没有 @snprintf 的 declare,问题会 + # 被拖到后端才炸(llc: "use of undefined value '@snprintf'")——按"隐式 + # 提供"原则在使用点补 declare(先例:AsyncGenMixin 的 GetTickCount64)。 + # 签名三段固定参数(i8*, i64, i8*)+ 变参,与下面的 build_call 一致。 + if self.Gen.CallGenBase.find_func_in_module(mod, "snprintf") is None: + snprintf_decl: llvmlite.Function* = llvmlite.create_declare(pool, mod, "snprintf", i32_ty) + if snprintf_decl is not None: + snprintf_decl.IsVarArg = 1 + llvmlite.add_param(pool, snprintf_decl, i8_ty, "buf") + llvmlite.add_param(pool, snprintf_decl, llvmlite.Int64(pool), "size") + llvmlite.add_param(pool, snprintf_decl, i8_ty, "fmt") # snprintf(buf, FSTR_BUF_SIZE, fmt, args...) size_val: llvmlite.Value* = llvmlite.const_int64(pool, FSTR_BUF_SIZE) buf_ptr.Next = size_val