diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-22 15:32:49 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-22 15:32:49 +0000 |
| commit | 713a313b06256a13ddefa5e257e3b80f8aa808ba (patch) | |
| tree | 0288e9e9e44b9765cf2285fa3adaf82963612180 /lib/CodeGen/CallGen.cc | |
| parent | 5a5a14be5e2683a42906da4b2ad19690e230c871 (diff) | |
feat(codegen): convert implicitly between CHAR and STRING
A CHAR becomes a one-character STRING in &, comparisons, assignment,
parameter passing and RETURN. A STRING becomes a CHAR in assignment,
parameter passing and RETURN, with a runtime error when its length is
not 1. CHAR with INTEGER or BOOLEAN still does not convert.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/CallGen.cc')
| -rw-r--r-- | lib/CodeGen/CallGen.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/CodeGen/CallGen.cc b/lib/CodeGen/CallGen.cc index 4631332..43c0dd4 100644 --- a/lib/CodeGen/CallGen.cc +++ b/lib/CodeGen/CallGen.cc @@ -225,6 +225,30 @@ const FuncSig *CodeGen::resolveCall(const std::string &Name, } } if (Ordinary) return Ordinary; + // Failing an exact match, CHAR and STRING arguments convert into one + // another; the overload must be unique. + if (!HasTemplates && !HasExplicit) { + auto Scalar = [](const TypeInfo *T) { return T && (T->Kind == TypeKind::Char || T->isString()); }; + const FuncSig *Converted = nullptr; + for (const FuncSig *Sig : Overloads) { + if (Sig->Params.size() != Actual.size()) continue; + bool Match = true; + for (size_t I = 0; I < Actual.size() && Match; ++I) { + const ParamSig &P = Sig->Params[I]; + const TypeInfo *Formal = Types->resolve(P.TypeName); + Match = Actual[I].Rank == (P.IsArray ? P.Rank : 0) && Actual[I].Type && + (Actual[I].Type->sameType(Formal) || + (!P.IsByRef && !P.IsArray && Scalar(Actual[I].Type) && Scalar(Formal))); + } + if (!Match) continue; + if (Converted) { + reportError("Ambiguous call to %s(%s)", Name.c_str(), Key.c_str()); + return nullptr; + } + Converted = Sig; + } + if (Converted) return Converted; + } if (HasTemplates) { // A matching non-variadic template wins before any variadic candidate. for (bool Variadic : {false, true}) { |
