refactor(ffi-linkage): Phase 9.3-src — purge 'foreign' from src/ comments + a user-facing diagnostic

Reword every 'foreign' comment to the extern/runtime-class vocabulary matching the
renamed identifiers (foreign call→extern call, foreign class→runtime class, foreign
path→runtime path, the #foreign-literal comment mentions → extern, etc.). Also fixes
two USER-FACING issues: the 'expected … #foreign … after type annotation' parse error
no longer advertises the removed keyword, and the Android 'no #jni_main' help
diagnostic now shows '#jni_class(…) extern' instead of the rejected '#foreign
#jni_class'. Removed the now-dead prefix-#foreign-vs-postfix conflict branch in
parseRuntimeClassDecl (the caller rejects #foreign before it runs).

src/ now contains 'foreign' ONLY in the hash_foreign token machinery + its 4
rejection messages — the deprecation mechanism (kept per the 9.0 recommendation; the
message MUST name #foreign to guide migration). Snapshot-neutral; suite green
(646 corpus / 444 unit, 0 failed).
This commit is contained in:
agra
2026-06-15 09:35:00 +03:00
parent e99383fcb4
commit dc51c4b5bf
35 changed files with 172 additions and 180 deletions

View File

@@ -35,7 +35,7 @@ const Value = interp_mod.Value;
// The vendored error-trace ring buffer (library/vendors/sx_trace_runtime/sx_trace.c)
// is linked into the compiler. Comptime `#run` evaluation pushes frames to it via
// foreign `sx_trace_push` calls; after a `#run` we read it here to render the
// extern `sx_trace_push` calls; after a `#run` we read it here to render the
// return trace for an escaping comptime error (E5.2).
extern fn sx_trace_len() u32;
extern fn sx_trace_frame_at(i: u32) u64;
@@ -371,7 +371,7 @@ pub const LLVMEmitter = struct {
self.ffiCtors().emitObjcSelectorInit();
// Pass 2.5b: Emit Obj-C class-pair registration constructor for
// sx-defined classes (M1.2 A.4+). Runs BEFORE the foreign
// sx-defined classes (M1.2 A.4+). Runs BEFORE the runtime
// class-cache populator (2.5c) so a sx-defined class is already
// registered with the Obj-C runtime by the time
// `objc_getClass(\"SxFoo\")` runs to populate the Phase 3.1
@@ -888,7 +888,7 @@ pub const LLVMEmitter = struct {
const llvm_global = c.LLVMAddGlobal(self.llvm_module, llvm_ty, name_z.ptr);
// Extern globals (`<name> : <type> #foreign;`) resolve at link time
// Extern globals (`<name> : <type> extern;`) resolve at link time
// to a libSystem / framework symbol — no initializer, default linkage.
if (global.is_extern) {
c.LLVMSetLinkage(llvm_global, c.LLVMExternalLinkage);
@@ -1242,7 +1242,7 @@ pub const LLVMEmitter = struct {
// main always returns i32 at the LLVM level (JIT expects it)
const raw_ret_ty = self.toLLVMType(func.ret);
const needs_c_abi = func.is_extern or func.call_conv == .c;
// A foreign `-> string` / `-> ?string` receives ONE `char *` from C;
// An extern `-> string` / `-> ?string` receives ONE `char *` from C;
// the fat sx value is synthesized at the call site (emitCall's
// cstrReturnToSx). Never sret — the C callee knows nothing about an
// out-pointer.
@@ -1259,7 +1259,7 @@ pub const LLVMEmitter = struct {
else if (needs_c_abi) self.abiCoerceParamTypeEx(func.ret, raw_ret_ty, func.is_extern)
else raw_ret_ty;
// Build parameter types — apply C ABI coercion for foreign/callconv(.c) functions.
// Build parameter types — apply C ABI coercion for extern/callconv(.c) functions.
// When uses_sret, prepend the sret pointer at index 0.
const sret_offset: usize = if (uses_sret) 1 else 0;
const param_count: c_uint = @intCast(func.params.len + sret_offset);
@@ -1322,7 +1322,7 @@ pub const LLVMEmitter = struct {
// Apple ARM64 ABI for >16B non-HFA composites: pass by reference
// via a pointer in the next int register (NOT via LLVM's `byval`
// attribute, which lowers the struct on the stack — incompatible
// with what `clang` emits and what foreign C callees expect).
// with what `clang` emits and what extern C callees expect).
// abiCoerceParamType returned `ptr` for these slots, so the formal
// param IS a plain pointer; the prologue loads the struct back.
@@ -2267,7 +2267,7 @@ pub const LLVMEmitter = struct {
return .none;
}
/// Build the sx-level value for a foreign call that returned a `char *`:
/// Build the sx-level value for a extern call that returned a `char *`:
/// `{ptr, strlen(ptr)}` for `string` (NULL → `{null, 0}`), wrapped in
/// `{string, i1}` with `has = ptr != null` for `?string`. The strlen call
/// is branch-guarded — `select` would evaluate `strlen(NULL)`.
@@ -2452,12 +2452,12 @@ pub const LLVMEmitter = struct {
return null;
}
/// Resolve the IR type of a foreign-call argument ref. Every FFI arg ref is
/// Resolve the IR type of a extern-call argument ref. Every FFI arg ref is
/// a real function param or block instruction result, so a `null` here is a
/// codegen invariant violation, not a recoverable case: return the dedicated
/// `.unresolved` sentinel — never `.void`/`.i64` — so the failure cannot be
/// mistaken for a real type and trips `toLLVMType`'s hard tripwire at the call
/// site instead of silently emitting a void-typed foreign argument.
/// site instead of silently emitting a void-typed extern argument.
pub fn argIRTypeOrFail(self: *LLVMEmitter, arg_ref: Ref) TypeId {
return self.getRefIRType(arg_ref) orelse .unresolved;
}
@@ -2519,7 +2519,7 @@ pub const LLVMEmitter = struct {
return self.typeLowering().toLLVMType(ty);
}
// ── C ABI coercion for foreign functions ──────────────────────────
// ── C ABI coercion for extern functions ──────────────────────────
// The coercion logic lives in `backend/llvm/abi.zig` (`AbiLowering`);
// these stay the facade entry points (callers in signature/call emission +
// the block-trampoline path use abiCoerceParamTypeEx directly).