Files
ViperC/App
TermiNexus 4c34e396a4 fix(call): align cross-module calls with the callee symbol's signature
mlirlite.build_call composes the llvm.call function type from the argument values and the
caller-supplied return type; it never consults the callee. Declares are synthesized the same
way (_ensure_method_declare appends missing params from the caller's own argument values and
never compares return types), so nothing verified that a call site agreed with the definition.
Two modules could therefore emit incompatible calls for the same symbol, which only the MLIR
verifier rejected later:

    llvm.func @MapHHDM(i64, i64, i64)                 (definition, void)
    llvm.call @MapHHDM(i64, i64, i32) -> i32          (caller)

- after the declare/definition exists, conform every fixed argument to its parameter type and
  emit the call with the symbol's return type (_conform_call_args / _call_symbol_ret_ty)
- fail fast when a cross-module call site resolves a return type the symbol disagrees with,
  instead of emitting both and letting mlir-opt report an operand type mismatch
- record a module-level `def` without a return annotation as `void` in the vpi return-annotation
  cache (previously a hardcoded i32, so callers invented an i32 return for void exports);
  extern/state C declarations and methods keep the legacy default
2026-10-29 15:53:43 +08:00
..